mysql最常用的索引结构是btree(O(log(n))),但是总有一些情况下我们为了更好的性能希望能使用别的类型的索引。hash就是其中一种选择,例如我们在通过用户名检索用户id的时候,他们总是一对一的关系,用到的操作符只是=而已,假如使用hash作为索引数据结构的话,时间复杂度可以降到O(1)。不幸的是,目前的mysql版本(5.6)中,hash只支持MEMORY和NDB两种引擎,而我们最常用的INNODB和MYISAM都不支持hash类型的索引。 不管怎样,还是要了解一下这两种索引的区别,下面翻译自mysql官网文档中对这两者的解释。 B-Tree 索引特征 B-Tree索引可以被用在像=,>,>=,<,<=和BETWEEN这些比较操作符上。而且还可以用于LIKE操作符,只要它的查询条件是一个不以通配符开头的常量。像下面的语句就可以使用索引: 复制代码 代码如下: SELECT * FROM tbl_name WHERE key_col LIKE "Patrick%"; SELECT * FROM tbl_name WHERE key_col LIKE "Pat%_ck%";
下面这两种情况不会使用索引: 复制代码 代码如下: SELECT * FROM tbl_name WHERE key_col LIKE "%Patrick%"; SELECT * FROM tbl_name WHERE key_col LIKE other_col;
第一条是因为它以通配符开头,第二条是因为没有使用常量。 假如你使用... LIKE "%string%"而且string超过三个字符,MYSQL使用Turbo Boyer-Moore algorithm算法来初始化查询表达式,然后用这个表达式来让查询更迅速。 一个这样的查询col_name IS NULL是可以使用col_name的索引的。 任何一个没有覆盖所有WHERE中AND级别条件的索引是不会被使用的。也就是说,要使用一个索引,这个索引中的第一列需要在每个AND组中出现。 下面的WHERE条件会使用索引: 复制代码 代码如下: ... 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 /* 优化成 "index_part1="hello"" */ ... WHERE index_part1="hello" AND index_part3=5 /* 可以使用 index1 的索引但是不会使用 index2 和 index3 */ ... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
下面的WHERE条件不会使用索引: 复制代码 代码如下: /* index_part1 没有被使用到 */ ... WHERE index_part2=1 AND index_part3=2 /* 索引 index 没有出现在每个 where 子句中 */ ... WHERE index=1 OR A=10 /* 没有索引覆盖所有列 */ ... WHERE index_part1=1 OR index_part2=10