理解 B 树和哈希数据结构有助于预测不同查询在使用这些数据结构作为索引的不同存储引擎上的性能,特别是对于MEMORY存储引擎,它允许你选择 B 树或哈希索引。Understanding the B-tree and hash data structures can help
predict how different queries perform on different storage
engines that use these data structures in their indexes,
particularly for the MEMORY storage engine
that lets you choose B-tree or hash indexes.
B 树索引可以用于使用 =、>、>=、<、<= 或 BETWEEN 运算符的列比较。 如果 LIKE 的参数是一个不以通配符字符开头的常量字符串,索引也可以用于 LIKE 比较。 例如,以下 SELECT 语句使用索引:A B-tree index can be used for column comparisons in
expressions that use the
=,
>,
>=,
<,
<=,
or BETWEEN operators. The index
also can be used for LIKE
comparisons if the argument to
LIKE is a constant string that
does not start with a wildcard character. For example, the
following SELECT statements use
indexes:
SELECT * FROMtbl_nameWHEREkey_colLIKE 'Patrick%'; SELECT * FROMtbl_nameWHEREkey_colLIKE 'Pat%_ck%';
在第一个语句中,只考虑 'Patrick'
<= key_col <
'Patricl' 的行。在第二个语句中,只考虑 'Pat' <=
key_col < 'Pau' 的行。In the first statement, only rows with 'Patrick'
<= are considered. In the second statement,
only rows with key_col <
'Patricl''Pat' <=
are
considered.key_col < 'Pau'
以下 SELECT 语句不使用索引:The following SELECT statements
do not use indexes:
SELECT * FROMtbl_nameWHEREkey_colLIKE '%Patrick%'; SELECT * FROMtbl_nameWHEREkey_colLIKEother_col;
在第一个语句中,LIKE 值以通配符字符开头。在第二个语句中,LIKE 值不是常量。In the first statement, the LIKE
value begins with a wildcard character. In the second
statement, the LIKE value is not
a constant.
如果你使用 ... LIKE
'%string%' 并且 string 长度超过三个字符,MySQL 会使用 Turbo Boyer-Moore 算法 初始化字符串的模式,然后使用该模式更快地执行搜索。If you use ... LIKE
'% and
string%'string is longer than three
characters, MySQL uses the Turbo
Boyer-Moore algorithm to initialize the pattern for
the string and then uses this pattern to perform the search
more quickly.
如果 col_name 有索引,使用 col_name IS
NULL 进行的搜索将会使用索引。A search using employs indexes if
col_name IS
NULLcol_name is indexed.
任何未跨越AND子句中所有级别的索引都不能用于优化查询。换句话说,要能够使用索引,索引的前缀必须在每个WHERE组中使用。AND对于Any index that does not span all
AND levels in the
WHERE clause is not used to optimize the
query. In other words, to be able to use an index, a prefix of
the index must be used in every
AND group.
以下 WHERE 子句会使用索引:The following WHERE clauses use indexes:
... WHEREindex_part1=1 ANDindex_part2=2 ANDother_column=3 /*index= 1 ORindex= 2 */ ... WHEREindex=1 OR A=10 ANDindex=2 /* optimized like "index_part1='hello'" */ ... WHEREindex_part1='hello' ANDindex_part3=5 /* Can use index onindex1but not onindex2orindex3*/ ... WHEREindex1=1 ANDindex2=2 ORindex1=3 ANDindex3=3;
以下 WHERE 子句 不会 使用索引:These WHERE clauses do
not use indexes:
/*index_part1is not used */ ... WHEREindex_part2=1 ANDindex_part3=2 /* Index is not used in both parts of the WHERE clause */ ... WHEREindex=1 OR A=10 /* No index spans all rows */ ... WHEREindex_part1=1 ORindex_part2=10
有时即使存在索引,MySQL 也不会使用它。出现这种情况的一种情况是,当优化器估计使用索引将导致 MySQL 访问表中很大一部分行时。(在这种情况下,表扫描可能会快得多,因为它需要更少的寻址操作。)然而,如果这样的查询使用 LIMIT 只检索部分行,MySQL 仍会使用索引,因为它可以更快地找到要在结果中返回的少量行。Sometimes MySQL does not use an index, even if one is
available. One circumstance under which this occurs is when
the optimizer estimates that using the index would require
MySQL to access a very large percentage of the rows in the
table. (In this case, a table scan is likely to be much faster
because it requires fewer seeks.) However, if such a query
uses LIMIT to retrieve only some of the
rows, MySQL uses an index anyway, because it can much more
quickly find the few rows to return in the result.
哈希索引与刚才讨论的索引有些不同的特性:Hash indexes have somewhat different characteristics from those just discussed:
它们只用于使用
=或<=>操作符的相等比较(但速度 非常 快)。它们不用于查找值范围的比较操作符,例如<。依赖这种类型单值查找的系统被称为 “键值存储”;在此类应用中使用 MySQL 时,应尽可能使用哈希索引。They are used only for equality comparisons that use the=or<=>operators (but are very fast). They are not used for comparison operators such as<that find a range of values. Systems that rely on this type of single-value lookup are known as “key-value stores”; to use MySQL for such applications, use hash indexes wherever possible.优化器无法使用哈希索引来加速
ORDER BY操作。(这种类型的索引不能用于按顺序搜索下一个条目。)The optimizer cannot use a hash index to speed upORDER BYoperations. (This type of index cannot be used to search for the next entry in order.)MySQL 无法大致确定两个值之间有多少行(这被范围优化器用来决定使用哪个索引)。如果你将
MyISAM或InnoDB表更改为哈希索引的MEMORY表,这可能会影响某些查询。MySQL cannot determine approximately how many rows there are between two values (this is used by the range optimizer to decide which index to use). This may affect some queries if you change aMyISAMorInnoDBtable to a hash-indexedMEMORYtable.只有完整的键才能用于搜索行。(对于 B 树索引,键的任何最左前缀都可以用于查找行。)Only whole keys can be used to search for a row. (With a B-tree index, any leftmost prefix of the key can be used to find rows.)