mita2 database life

主にMySQLに関するメモです

MySQL ヒストグラムはバックアップされるか

MySQL 8.0 でヒストグラム統計が追加されました。従来、MySQLはデータが均等に分布していると仮定し、実行計画を組み立てていました。 ヒストグラムを使えば正確なデータの分布に基づいて、より最適な実行計画が選択されるようになります。

yakst.com

ヒストグラムANALIZE TABLE 〜 UPDATE HISTOGRAM で追加します。そして、information_schema.column_statistics を参照すると、ヒストグラムが追加されていることが確認できます。

mysql> ANALYZE TABLE t UPDATE HISTOGRAM ON val;
+-------+-----------+----------+------------------------------------------------+
| Table | Op        | Msg_type | Msg_text                                       |
+-------+-----------+----------+------------------------------------------------+
| t.t   | histogram | status   | Histogram statistics created for column 'val'. |
+-------+-----------+----------+------------------------------------------------+
1 row in set (0.06 sec)

mysql> SELECT * FROM  information_schema.column_statistics \G
*************************** 1. row ***************************
SCHEMA_NAME: t
 TABLE_NAME: t
COLUMN_NAME: val
  HISTOGRAM: {"buckets": [[93, 139, 0.009009009009009009, 3], [153, 326, 0.021021021021021023, 4],〜
1 row in set (0.00 sec)

ヒストグラム を追加しても、CREATE TABLE文 には、変化がないようです。

mysql> SHOW CREATE TABLE t \G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `pk` bigint unsigned NOT NULL AUTO_INCREMENT,
  `val` int DEFAULT NULL,
  UNIQUE KEY `pk` (`pk`)
) ENGINE=InnoDB AUTO_INCREMENT=334 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.00 sec)

mysqldumpmysqlsh で論理バックアップを取得した場合、どうなるんでしょうか?

  • mysqldump

ヒストグラムの定義自体はバックアップされるようです(当たり前)。 取得したヒストグラム統計はバックアップをインポートするときに再度、取得しなおされます。

$ mysqldump -uroot t t | grep HISTOGRAM
/*!80002 ANALYZE TABLE `t` UPDATE HISTOGRAM ON `val` WITH 100 BUCKETS */;
  • mysqlsh util.dumpTable

MySQL Shell もちゃんと対応してますね。JSONhistograms が含まれています。

$ cat t@t.json
{
    "options": {
        "schema": "t",
        "table": "t",
        "columns": [
            "pk",
            "val"
        ],
        "primaryIndex": "",
        "compression": "zstd",
        "defaultCharacterSet": "utf8mb4",
        "fieldsTerminatedBy": "\t",
        "fieldsEnclosedBy": "",
        "fieldsOptionallyEnclosed": false,
        "fieldsEscapedBy": "\\",
        "linesTerminatedBy": "\n"
    },
    "triggers": [],
    "histograms": [
        {
            "column": "val",
            "buckets": 100
        }
    ],
    "includesData": true,
    "includesDdl": true,
    "extension": "tsv.zst",
    "chunking": true
}

MySQL 8.0 より前の mysqldump を使うとヒストグラムは移植されない

ヒストグラムMySQL 8.0 の機能なので、MySQL 5.7 の mysqldump で 8.0のテーブルをダンプするとヒストグラムの定義は抜け落ちてしまいます。

$ mysqldump --version
mysqldump  Ver 10.13 Distrib 5.7.31, for Linux (x86_64)

$ mysqldump -ubk -pPassword -h mysql80 t t | grep HISTO
(何も出力されない)

来週はMySQLユーザ会会

来週 11/25(水) は MyNA会ですね!楽しみです。 mysql.connpass.com