Indexes are used to find rows with specific column values quickly. 索引用于快速查找具有特定列值的行。Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows. 如果没有索引,MySQL必须从第一行开始,然后通读整个表以找到相关的行。The larger the table, the more this costs. 桌子越大,花费就越多。If the table has an index for the columns in question, MySQL can quickly determine the position to seek to in the middle of the data file without having to look at all the data. 如果表中的列具有索引,MySQL可以快速确定要在数据文件中间寻找的位置,而不必查看所有数据。This is much faster than reading every row sequentially.这比按顺序读取每一行要快得多。
Most MySQL indexes (大多数MySQL索引(主键索引、惟一性索引、索引和全文索引)都存储在B树中。PRIMARY KEY
, UNIQUE
, INDEX
, and FULLTEXT
) are stored in B-trees. Exceptions: Indexes on spatial data types use R-trees; 例外情况:空间数据类型的索引使用R-树;内存表也支持哈希索引;MEMORY
tables also support hash indexes; InnoDB
uses inverted lists for FULLTEXT
indexes.InnoDB
使用倒排列表作为全文索引。
In general, indexes are used as described in the following discussion. 一般来说,索引的使用方法如下所述。Characteristics specific to hash indexes (as used in 第8.3.9节,“B树和哈希索引的比较”中描述了哈希索引(在内存表中使用)的特定特征。MEMORY
tables) are described in Section 8.3.9, “Comparison of B-Tree and Hash Indexes”.
MySQL uses indexes for these operations:MySQL使用索引执行以下操作:
To find the rows matching a 快速查找与WHERE
clause quickly.WHERE
子句匹配的行。
To eliminate rows from consideration. 不考虑行。If there is a choice between multiple indexes, MySQL normally uses the index that finds the smallest number of rows (the most selective index).如果在多个索引之间有选择的话,MySQL通常使用查找最少行数的索引(最有选择性的索引)。
If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to look up rows. 如果表有多列索引,则优化器可以使用索引的任何最左侧前缀来查找行。For example, if you have a three-column index on 例如,如果在(col1, col2, col3)
, you have indexed search capabilities on (col1)
, (col1, col2)
, and (col1, col2, col3)
. (col1, col2, col3)
上有一个三列索引,则在(col1)
、(col1, col2)
和(col1, col2, col3)
上有索引搜索功能。For more information, see Section 8.3.6, “Multiple-Column Indexes”.有关更多信息,请参阅第8.3.6节,“多列索引”。
To retrieve rows from other tables when performing joins. 在执行联接时从其他表中检索行。MySQL can use indexes on columns more efficiently if they are declared as the same type and size. 如果将列声明为相同的类型和大小,MySQL可以更有效地使用这些列上的索引。In this context, 在此上下文中,如果VARCHAR
and CHAR
are considered the same if they are declared as the same size. VARCHAR
和CHAR
声明为相同的大小,则认为它们是相同的。For example, 例如,VARCHAR(10)
and CHAR(10)
are the same size, but VARCHAR(10)
and CHAR(15)
are not.VARCHAR(10)
和CHAR(10)
的大小相同,但VARCHAR(10)
和CHAR(15)
的大小不同。
For comparisons between nonbinary string columns, both columns should use the same character set. 对于非二进制字符串列之间的比较,两列应使用相同的字符集。For example, comparing a 例如,比较utf8
column with a latin1
column precludes use of an index.utf8
列和latin1
列可以避免使用索引。
Comparison of dissimilar columns (comparing a string column to a temporal or numeric column, for example) may prevent use of indexes if values cannot be compared directly without conversion. 比较不同的列(例如,将字符串列与时间或数字列进行比较)可能会阻止使用索引,如果值不能在没有转换的情况下直接比较。For a given value such as 对于给定的值(如数字列中的1),它可能与字符串列中的任意数量的值(如1
in the numeric column, it might compare equal to any number of values in the string column such as '1'
, ' 1'
, '00001'
, or '01.e1'
. '1'
、' 1'
、'00001'
或'01.e1'
)进行比较。This rules out use of any indexes for the string column.这就排除了对字符串列使用任何索引的可能性。
To find the 查找特定索引列MIN()
or MAX()
value for a specific indexed column key_col
. key_col
的MIN()
或MAX()
值。This is optimized by a preprocessor that checks whether you are using 这是通过一个预处理器来优化的,该预处理器检查是否对索引中WHERE
on all key parts that occur before key_part_N
= constant
key_col
in the index. key_col
之前出现的所有键部分使用WHERE
。key_part_N
= constant
In this case, MySQL does a single key lookup for each 在本例中,MySQL对每个MIN()
or MAX()
expression and replaces it with a constant. MIN()
或MAX()
表达式执行单键查找,并用常量替换它。If all expressions are replaced with constants, the query returns at once. 如果所有表达式都替换为常量,则查询将立即返回。For example:例如:
SELECT MIN(key_part2
),MAX(key_part2
) FROMtbl_name
WHEREkey_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
ORDER BY
、key_part1
、key_part2
)。If all key parts are followed by 如果所有关键部件后面都跟有DESC
, the key is read in reverse order. DESC
,则按相反顺序读取。(Or, if the index is a descending index, the key is read in forward order.) (或者,如果索引是降序索引,则按前进顺序读取键。)See Section 8.2.1.16, “ORDER BY Optimization”, Section 8.2.1.17, “GROUP BY Optimization”, and Section 8.3.13, “Descending Indexes”.参见第8.2.1.16节,“ORDER BY优化”、第8.2.1.17节,“GROUP BY优化”和第8.3.13节,“降序索引”。
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:如果查询仅从表中使用包含在某些索引中的列,则可以从索引树中检索所选值以提高速度:
SELECTkey_part3
FROMtbl_name
WHEREkey_part1
=1
Indexes are less important for queries on small tables, or big tables where report queries process most or all of the rows. 索引对于小表或报表查询处理大部分或所有行的大表的查询不太重要。When a query needs to access most of the rows, reading sequentially is faster than working through an index. 当查询需要访问大多数行时,按顺序读取比遍历索引要快。Sequential reads minimize disk seeks, even if not all the rows are needed for the query. 即使查询不需要所有的行,顺序读取也可以最小化磁盘查找。See Section 8.2.1.23, “Avoiding Full Table Scans” for details.详见第8.2.1.23节,“避免全表扫描”。