MySQL可以创建复合索引,即在多个列上的索引,也有人称之为联合索引。一个索引最多可以由16列组成。对于某些数据类型,可以对列的前缀进行索引。即前缀索引:对于内容很长的列,比如blob类型, text类型或者很长的varchar类型列,必须使用前缀索引,mysql不允许索引这些列的完整长度,只截取前面部分字段作为索引。创建方式:ALTER TABLE table_name ADD KEY(column_name(prefix_length));prefix_length就是截取的前缀长度。
对使用到复合索引里所有列为条件的查询中,MySQL可以用到复合索引。或者查询条件仅有第一列,或者前两列,或者前三列,前n列等的查询,复合索引都起效。 也就是说,复合索引的创建,索引的各列是有顺序讲究的。对于索引(col1, col2, col3)
,在这个索引下,查询条件为 (col1)或
(col1, col2)或
(col1, col2, col3)
都是起效的。如果在索引的定义以正确的顺序指定,则单个复合索引可以为同一表上的多种查询加速。例如对于索引INDEX name (last_name,first_name,age).那么一下查询可以利用上索引进行加速:
SELECT * FROM test WHERE last_name='Tom';
SELECT * FROM test WHERE last_name='Tom' AND (first_name='Cat' OR first_name='Cat');
SELECT * FROM test WHERE first_name ='Cat' AND last_name='Tom' AND age=18;
但是不可用为如下情形查询加速:
SELECT * FROM test WHERE last_name='Tom' AND age=18;
SELECT * FROM test WHERE first_name='Cat';
复合索引可以视为一个有序数组,这个数组的所有行包含了通过连接索引列的值创建的值。
注意:有一个可以代替使用复合索引的方法,就是你可以根据其他列的信息引入“散列”列,也称hash列。这个额外添加的列数据往往很短,很理想的,它是唯一的且已编制的索引,则它可能比一个长长的复杂的复合索引效率更快。 在MySQL中,创建这个额外的hash值列非常简单。代码如下: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和first_name列的复合索引。 该索引可用于条件在值已知范围的last_name和first_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上用的是独立的单列索引,或者你还在这个表上建立了多个涉及到col1或col2的索引。MySQL在执行这条语句会使用哪个索引呢?MySQL的优化程序会尝试使用索引合并优化机制进行优化(合并优化机制这里不介绍),或尝试通过确定哪个索引能排除更多行来查找限制性最强的索引,就决定使用哪个索引来获取行。