索引用于快速查找具有特定列值的行。如果没有索引,MySQL 必须从第一行开始,然后通读整个表以找到相关行。桌子越大,成本就越高。如果表有相关列的索引,MySQL 可以快速确定要在数据文件中间查找的位置,而无需查看所有数据。这比顺序读取每一行要快得多。
大多数 MySQL 索引(PRIMARY KEY
、
UNIQUE
、INDEX
和
FULLTEXT
)都存储在
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 可以更有效地使用列上的索引。在这种情况下, 如果它们被声明为相同的大小,则被认为是相同的
VARCHAR
。CHAR
例如,VARCHAR(10)
和CHAR(10)
是相同的大小,但VARCHAR(10)
和CHAR(15)
不是。对于非二进制字符串列之间的比较,两列应使用相同的字符集。例如,将
utf8
列与latin1
列进行比较会排除使用索引。如果不转换就无法直接比较值,则比较不同的列(例如,将字符串列与时间或数字列进行比较)可能会阻止使用索引。对于数字列中的给定值
1
,它可能与字符串列中的任意数量的值(例如'1'
、' 1'
、'00001'
或)进行比较'01.e1'
。这排除了对字符串列使用任何索引。To find the
MIN()
orMAX()
value for a specific indexed columnkey_col
. This is optimized by a preprocessor that checks whether you are usingWHERE
on all key parts that occur beforekey_part_N
=constant
key_col
in the index. In this case, MySQL does a single key lookup for eachMIN()
orMAX()
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
). If all key parts are followed bykey_part1
,key_part2
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 节,“避免全表扫描”。