MySQL 8.0では最新のUnicode 9.0がutf8mb4
という名前でサポートされています。utf8mb4
はそれぞれの文字が1から4バイトの可変長です。
可変長の文字数とバイト数が少し異なるケースはたくさんあり例えば次のようなケースがあげられます。
VARCHAR(n)
で作成した時、nは文字列長を表します。データの保存に必要なバイト数は(多くの場合はこれより小さいのですが)最大この4倍となりえます。utf8mb4
をVARCHAR
、CHAR
、TEXT
データ型の(インデックス内およびテーブルの行にて)可変長として保存しています。utf8mb4
文字セットを利用している場合は一時テーブルがより大きくなったり、より早くディスクにあふれたりすることになる場合があります。EXPLAIN
は常にインデックスの可変長(バイト長)の最大長を示します。もっと少ない領域しか必要とならない場合がしばしば発生します。例37は、latin1文字セットでCHAR(52)
の列へのインデックスを利用していることを伝えているEXPLAIN
となります。テーブルをutf8mb4
に変換した後、必要な保存容量は増えませんが、EXPLAIN
ではkey_length
が増えていることが確認できます。
EXPLAIN
がインデックスの最大キー長を示す(latin1文字セットにて) EXPLAIN FORMAT=JSON
SELECT * FROM Country WHERE name='Canada';
{
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "1.20"
},
"table": {
"table_name": "Country",
"access_type": "ref",
"possible_keys": [
"Name"
],
"key": "Name",
"used_key_parts": [
"Name"
],
"key_length": "52", # CHAR(52)
"ref": [
"const"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 1,
"filtered": "100.00",
"cost_info": {
"read_cost": "1.00",
"eval_cost": "0.20",
"prefix_cost": "1.20",
"data_read_per_join": "264"
},
"used_columns": [
"Code",
"Name",
"Continent",
"Region",
"SurfaceArea",
"IndepYear",
"Population",
"LifeExpectancy",
"GNP",
"GNPOld",
"LocalName",
"GovernmentForm",
"HeadOfState",
"Capital",
"Code2"
]
}
}
}
EXPLAIN
がインデックスの最大キー長を示す(utfmb4文字セットにて) ALTER TABLE Country CONVERT TO CHARACTER SET utf8mb4;
EXPLAIN FORMAT=JSON
SELECT * FROM Country WHERE name='Canada';
{
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "1.20"
},
"table": {
"table_name": "Country",
"access_type": "ref",
"possible_keys": [
"Name"
],
"key": "Name",
"used_key_parts": [
"Name"
],
"key_length": "208", # CHAR(52) * 4 = 208
"ref": [
"const"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 1,
"filtered": "100.00",
"cost_info": {
"read_cost": "1.00",
"eval_cost": "0.20",
"prefix_cost": "1.20",
"data_read_per_join": "968"
},
"used_columns": [
"Code",
"Name",
"Continent",
"Region",
"SurfaceArea",
"IndepYear",
"Population",
"LifeExpectancy",
"GNP",
"GNPOld",
"LocalName",
"GovernmentForm",
"HeadOfState",
"Capital",
"Code2"
]
}
}
}
行形式にDYNAMIC
、COMPACT
およびCOMPRESSED
を利用しているときは常に。通常は、以前のREDUNDANT
行形式は実用的な利用例がありません。 ↩