8.3.5 Multiple-Column Indexes 多列索引:
MySQL 可以创建符合索引(即,索引在多列上).
一个索引可能有最多16列组成,对于某些数据类型,你可以索引一个列的前缀。
Mysql 可以使用多列索引用于查询,测试索引里的所有的列,或者只测试第一列,前2列,前3列
如果你指定列按正确的顺序在索引定义里,一个单独额复合索引能加速几种类型的查询。
多列索引可以被认为是一个排序的数组, 索引的记录包含索引列的值。
注意:
作为一个非传统的对于一个复杂索引,你可以介绍一个列是hash的基于其他列的信息。
如果这个列是短的,合理的独特的,被索引的,它可能比一个wide索引在很多列上快。
在MySQL, 很容易使用额外的列:
SELECT * FROM tbl_name
WHERE hash_col=MD5(CONCAT(val1,val2))
AND col1=val1 AND col2=val2;
假设一个表有下面的列:
CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
INDEX name (last_name,first_name)
);
索引名字 name是last_name和forst_name 组合索引, 这个索引可以用于在查询里查找,
查找特定的值在一个已知的range用于包含last_name和first_name 值。
它也可以用于查询特定的last_name的值,因为last_name列是索引的最左前缀的
因此,索引name 是用于查找下面的查询:
SELECT * FROM test WHERE last_name=’Widenius’;
SELECT * FROM test
WHERE last_name=’Widenius’ AND first_name=’Michael’;
SELECT * FROM test
WHERE last_name=’Widenius’
AND (first_name=’Michael’ OR first_name=’Monty’);
SELECT * FROM test
WHERE last_name=’Widenius’
AND first_name >=’M’ AND first_name < ‘N’;
然而,索引name 不能用于下面的查询:
SELECT * FROM test WHERE first_name=’Michael’;
SELECT * FROM test
WHERE last_name=’Widenius’ OR first_name=’Michael’
假设你执行下面的查询:
SELECT * FROM tbl_name
WHERE col1=val1 AND col2=val2;
如果一个多列索引存在col1和col2,相应的记录可以被直接获取。
如果单独的 单列索引存在col1和col2,优化器尝试使用Index Merge optimization (see Section 8.2.1.4, “Index Merge
Optimization”),
或者尝试找到最严格的索引通过决定 那个索引能排除更多的行,
使用index 来获取行
如果表有一个多列索引,任何的最左前缀的索引可以用于优化查询记录。
比如, 如果你有3个列的索引在 (col1, col2, col3), 你可以搜索(col1), (col1, col2), and (col1, col2, col3).
SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;