B-Tree索引:不同的存储引擎可能使用不同的存储结构,例如NDB集群存储引擎内部实际使用T-Tree结构存储这种索引,其实其名字也是B-Tree;InnoDB则使用的是B+Tree。
B-Tree对索引列是顺序组织存储的,所以很适合查找范围数据。例如,在一个基于文本域的索引树上,按字母顺序传递连续的值进行查找是非常合适的,所以像“找出所有以I到K开头的名字”这样的查找效率会非常高。
假设有如下数据表:
1
2
3
4
5
6
7
|
CREATE
TABLE
People (
last_name
VARCHAR
(32)
NOT
NULL
,
first_name
VARCHAR
(32)
NOT
NULL
,
dob
date
NOT
NULL
,
gender enum (
'm'
,
'f'
)
NOT
NULL
,
KEY
(last_name, f irst_name, dob)
)
|
B-Tree索引适用于全键值、键值范围或键前缀查找其中键前缀查找只适用于根据最左前缀的查找。前面所述的索引对如下类型的查询有效。
全值匹配
全值匹配指的是和索引中的所有列进行匹配,例如前面提到的索引可用于查找姓名为CubaAllen、出生于1960-01-01的人。
匹配最左前级
前面提到的索引可用于查找所有姓为Allen的人,即只使用索引的第一列。匹配列前级也可以只匹配某一列的值的开头部分。例如前面提到的索引可用于查找所有以J开头的姓的人。这里也只使用了索引的第一列。
匹配范围值
例如前面提到的索引可用于查找姓在Allen和Barrymore之间的人。这里也只使用了索引的第一列。
精确匹配呆一列并范围匹配另一列
前面提到的索引也可用于查找所有姓为Allen,并且名字是字母K开头(比如Kim、Karl等)的人。即第一列last_name全匹配,第二列first_name范围匹配。
只访问索引的查询
B-Tree通常可以支持“只访问索引的查询”,即查询只需要访问索引,而无须访问数据行。后面我们将单独讨论这种“覆盖索引”的优化。
下面是一些关于B-Tree索引的限制:
•如果不是按照索引的最左列开始查找,则无法使用索引。例如上面例子中的索引在每用于查找名字为Bill的人,也无怯查找某个特定生日的人,因为这两列都不是最左数据列。类似地,也无战查找姓氏以某个字母结尾的人。
•不能跳过索引中的列。也就是说,前面所述的索引无法用于查找姓为Smith并且在某个特定日期出生的人。如果不指定名(first_name),则MySQL只能使用索引的第一列。
•如果查询中有某个列的范围(like between > < 都算范围查询)查询,则其右边所有列都无法使用索引优化查找。例如有查询 WHERE lastname='Smith’ AND firstname like '%J%'AND dob=’1976-12-23',这个查询只能使用索引的前两列,因为这里的like是一个范围条件(但是服务器可以把其余列用于其他目的)。如果范围查询列值的数量有限,那么可以通过使用多个等于条件来代替范围条件。
摘自《高性能mysql》