Documentation Home
MySQL 8.0 参考手册  / 第8章优化  / 8.3 优化和索引  /  8.3.1 MySQL如何使用索引

8.3.1 MySQL如何使用索引

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

大多数 MySQL 索引(PRIMARY KEYUNIQUEINDEXFULLTEXT)都存储在 B 树中。例外:空间数据类型的索引使用 R 树;MEMORY 表也​​支持散列索引InnoDB使用倒排列表作为FULLTEXT索引。

通常,索引的使用如以下讨论中所述。哈希索引特有的特征(在 MEMORY表中使用)在 第 8.3.8 节,“B-Tree 和哈希索引的比较”中描述。

MySQL 使用索引进行这些操作:

  • WHERE快速找到与子句 匹配的行。

  • 从考虑中消除行。如果在多个索引之间进行选择,MySQL 通常会使用找到最少行数的索引(最具 选择性的索引)。

  • 如果表有一个多列索引,那么优化器可以使用索引的任何最左边的前缀来查找行。例如,如果您在 上有一个三列索引 ,则您在、 和(col1, col2, col3)上具有索引搜索功能。有关详细信息,请参阅 第 8.3.5 节,“多列索引”(col1)(col1, col2)(col1, col2, col3)

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

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

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

  • To find the MIN() or MAX() value for a specific indexed column key_col. This is optimized by a preprocessor that checks whether you are using WHERE key_part_N = constant on all key parts that occur before key_col in the index. In this case, MySQL does a single key lookup for each MIN() or MAX() expression and replaces it with a constant. If all expressions are replaced with constants, the query returns at once. For example:

    SELECT MIN(key_part2),MAX(key_part2)
      FROM tbl_name WHERE key_part1=10;
  • To sort or group a table if the sorting or grouping is done on a leftmost prefix of a usable index (for example, ORDER BY key_part1, key_part2). If all key parts are followed by DESC, the key is read in reverse order. See Section 8.2.1.14, “ORDER BY Optimization”, and Section 8.2.1.15, “GROUP BY Optimization”.

  • In some cases, a query can be optimized to retrieve values without consulting the data rows. (An index that provides all the necessary results for a query is called a covering index.) If a query uses from a table only columns that are included in some index, the selected values can be retrieved from the index tree for greater speed:

    SELECT key_part3 FROM tbl_name
      WHERE key_part1=1

对于报表查询处理大部分或所有行的小表或大表,索引不太重要。当查询需要访问大部分行时,顺序读取比通过索引读取更快。顺序读取最小化磁盘寻道,即使查询不需要所有行。有关详细信息,请参阅第 8.2.1.20 节,“避免全表扫描”