文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  MySQL 如何使用索引

10.3.1 MySQL 如何使用索引

索引用于快速查找具有特定列值的记录。如果没有索引,MySQL 必须从第一条记录开始,然后读取整个表以找到相关的记录。表越大,成本就越高。如果表中针对相关列存在索引,MySQL 可以快速确定在数据文件中间查找的位置,而无需查看所有数据。这比顺序读取每一行要快得多。

大多数 MySQL 索引(PRIMARY KEYUNIQUEINDEXFULLTEXT)都存储在 B 树 中。例外:空间数据类型上的索引使用 R 树;MEMORY 表也支持 哈希索引InnoDBFULLTEXT 索引使用倒排列表。

一般来说,索引的使用方式如下所述。哈希索引(在 MEMORY 表中使用)的特定特征在 第 10.3.9 节,“B 树和哈希索引的比较” 中进行了描述。

MySQL 将索引用于以下操作:

  • 快速查找与 WHERE 子句匹配的记录。

  • 排除不符合条件的记录。如果可以在多个索引之间进行选择,MySQL 通常会使用找到记录数最少(最具 选择性)的索引。

  • 如果表具有多列索引,则优化器可以使用索引的任何最左侧前缀来查找记录。例如,如果您在 (col1, col2, col3) 上有一个三列索引,则您在 (col1)(col1, col2)(col1, col2, col3) 上具有索引搜索功能。有关更多信息,请参见 第 10.3.6 节,“多列索引”

  • 在执行连接时从其他表中检索记录。如果将列声明为相同的类型和大小,MySQL 可以更有效地使用它们上的索引。在这种情况下,如果将 VARCHARCHAR 声明为相同的大小,则认为它们是相同的。例如,VARCHAR(10)CHAR(10) 的大小相同,但 VARCHAR(10)CHAR(15) 的大小不同。

    对于非二进制字符串列之间的比较,两列应使用相同的字符集。例如,将 utf8mb4 列与 latin1 列进行比较会阻止使用索引。

    不同类型列的比较(例如,将字符串列与时间或数字列进行比较)可能会阻止使用索引,因为如果值无法在不转换的情况下直接进行比较。对于数字列中的给定值(例如 1),它可能与字符串列中的任意数量的值相等,例如 '1'' 1''00001''01.e1'。这排除了对字符串列使用任何索引的可能性。

  • 查找特定索引列 key_colMIN()MAX() 值。这通过预处理器进行了优化,该预处理器会检查您是否在索引中 key_col 之前的 所有键部分上使用了 WHERE key_part_N = constant。在这种情况下,MySQL 对每个 MIN()MAX() 表达式执行一次键查找,并将其替换为常量。如果所有表达式都被替换为常量,则查询会立即返回结果。例如:

    SELECT MIN(key_part2),MAX(key_part2)
      FROM tbl_name WHERE key_part1=10;
  • 如果排序或分组是在可用索引的最左侧前缀上完成的(例如,ORDER BY key_part1, key_part2),则对表进行排序或分组。如果所有键部分后都跟有 DESC,则按相反顺序读取键。(或者,如果索引是降序索引,则按顺序读取键。)请参阅第 10.2.1.16 节“ORDER BY 优化”第 10.2.1.17 节“GROUP BY 优化”第 10.3.13 节“降序索引”

  • 在某些情况下,可以优化查询以检索值,而无需查阅数据行。(为查询提供所有必要结果的索引称为覆盖索引。)如果查询仅使用表中包含在某个索引中的列,则可以从索引树中检索选定的值,以提高速度。

    SELECT key_part3 FROM tbl_name
      WHERE key_part1=1

对于小型表或大型表(其中报表查询处理大部分或所有行)的查询,索引不太重要。当查询需要访问大部分行时,顺序读取比通过索引工作更快。顺序读取最大限度地减少了磁盘查找,即使并非所有行都需要用于查询。有关详细信息,请参阅第 10.2.1.23 节“避免全表扫描”