文档首页
MySQL 8.4 参考手册
8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

MySQL 8.4 参考手册 / 10 优化 / 10.3 优化和索引 / 10.3.9 B 树和哈希索引的比较
中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

10.3.9 B 树索引与哈希索引的比较10.3.9 Comparison of B-Tree and Hash Indexes

理解 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 树索引特性B-Tree Index Characteristics

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 * FROM tbl_name WHERE key_col LIKE 'Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';

在第一个语句中,只考虑 'Patrick' <= key_col < 'Patricl' 的行。在第二个语句中,只考虑 'Pat' <= key_col < 'Pau' 的行。In the first statement, only rows with 'Patrick' <= key_col < 'Patricl' are considered. In the second statement, only rows with 'Pat' <= key_col < 'Pau' are considered.

以下 SELECT 语句不使用索引:The following SELECT statements do not use indexes:

SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_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 '%string%' and 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 col_name IS NULL employs indexes if col_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:

... WHERE index_part1=1 AND index_part2=2 AND other_column=3

    /* index = 1 OR index = 2 */
... WHERE index=1 OR A=10 AND index=2

    /* optimized like "index_part1='hello'" */
... WHERE index_part1='hello' AND index_part3=5

    /* Can use index on index1 but not on index2 or index3 */
... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;

以下 WHERE 子句 不会 使用索引:These WHERE clauses do not use indexes:

    /* index_part1 is not used */
... WHERE index_part2=1 AND index_part3=2

    /*  Index is not used in both parts of the WHERE clause  */
... WHERE index=1 OR A=10

    /* No index spans all rows  */
... WHERE index_part1=1 OR index_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 Index Characteristics

哈希索引与刚才讨论的索引有些不同的特性: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 up ORDER BY operations. (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 a MyISAM or InnoDB table to a hash-indexed MEMORY table.

  • 只有完整的键才能用于搜索行。(对于 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.)