美文网首页MySQL
字符集 - 非官方 MySQL 8.0 优化指南 - 学习笔记

字符集 - 非官方 MySQL 8.0 优化指南 - 学习笔记

作者: mokou591 | 来源:发表于2019-04-06 09:43 被阅读2次

    MySQL 8.0 支持 Unicode 9.0 的编码是utf8mb4。它是变长的,每个字符占用 1~4 字节。关于字节和字符类型的可变长度有许多细微差别:

    1. 当创建 VARCHAR(n) 列时,n 代表字符数。储存该类型所需的字节数最多可能达到 n 的 4 倍。
    2. 通常 InnoDB 储存引擎对于 VARCHAR, CHAR, TEXT 类型都会储存为可变长的 utf8mb4 编码,在索引和在行数据中都是这样。
    3. 内存临时表是定长的。这会导致在使用 utf8mb4 编码一些情况下,内存临时表要么更大,要么是大到要用硬盘来存放溢出内存的部分。
    4. 用于排序的缓冲区是变长的(从 5.7 版本起)。
    5. EXPLAIN 会展示变长索引的最大长度,但实际所需的储存空间通常低得多。

    例子37展示了 EXPLAIN 报告了使用 latin1 编码、 CHAR(52) 类型的索引使用情况。把表的储存编码修改为 utf8mb4 后,储存占用空间没有变大,但 EXPLAIN 的键长度 key_length 增加了:

    例子37: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": [
            ...
          ]
        }
      }
    }
    

    例子38:EXPLAIN 展示索引的最大键长度(utf8mb4 编码)

    -- 修改表编码为 utf8mb4
    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": [
            ...
          ]
        }
      }
    }
    

    译自:
    Character Sets - The Unofficial MySQL 8.0 Optimizer Guide

    相关文章

      网友评论

        本文标题:字符集 - 非官方 MySQL 8.0 优化指南 - 学习笔记

        本文链接:https://www.haomeiwen.com/subject/scckiqtx.html