Mysql组合索引以及最左原则(MySQL8.0产品⽂档)
MySQL可以创建组合索引(即 多列上的索引)。⼀个索引最多由16列组成,对于某些数据类型,你可以索引⼀个列的前缀,即前缀索引,可以只索引⼀个字段的指定部分内容
例如:
`CREATE TABLE test (blob_col BLOB,INDEX(blob_col(10)));`
MySQL 可以使⽤多个列的索引,测试索引中的所有列,或者只测试第⼀列,前两列,前三列等等,以此类推,如果在索引的定义中按照正确的顺序指定列,单个组合索引可以加速同⼀个表的多种查询速度
多列索引可以视为排序数组
注意:
作为复合索引的替代⽅法,可以引⼊⼀个基于其他列的信息“散列”的列。如果这个列很短,合理地唯⼀,并且有索引,那么它可能⽐许多列上的“宽”索引要快。在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)
);
以下查询时组合索引是⽣效的:
SELECT*FROM test WHERE last_name='Jones';
SELECT*FROM test
WHERE last_name='Jones'AND first_name='John';
SELECT*FROM test
WHERE last_name='Jones'
AND(first_name='John'OR first_name='Jon');
SELECT*FROM test
WHERE last_name='Jones'
AND first_name >='M'AND first_name <'N';
然⽽,name索引在以下的sql查中并没有使⽤到:
SELECT*FROM test WHERE first_name='John';
SELECT*FROM test
WHERE last_name='Jones'OR first_name='John';
假设使⽤了以下类似的sql:
SELECT*FROM tbl_name
WHERE col1=val1 AND col2=val2;
如果col1和col2上存在多列索引,则可以直接获取相应的⾏。如果col1和col2上存在单独的单列索引,那么优化器将尝试使⽤索引合并优化,或者通过确定排除更多⾏的索引并使⽤该索引获取⾏来尝试查限制性最强的索引
如果表有多列索引,则优化器可以使⽤索引的任何最左侧前缀来查⾏。例如,如果在(col1,col2,col3)上有⼀个三列索引,则在(col1)、(col1,col2)和(col1,col2,col3)上有索引搜索功能。
如果sql条件中的列⽆法组成索引最左边的前缀的⽅式,MySQL就不能使⽤索引执⾏查。
假设如下SELECT语句:
SELECT*FROM tbl_name WHERE col1=val1;
SELECT*FROM tbl_name WHERE col1=val1 AND col2=val2;
SELECT*FROM tbl_name WHERE col2=val2;mysql帮助文档
SELECT*FROM tbl_name WHERE col2=val2 AND col3=val3;
如果 (col1, col2, col3)存在索引,那只有前两个查询是⽤到索引的,后两个查询确实包含了索引列,但是并没有⽤上索引,因为(col2),(col2, col3) 并不是(col1, col2, col3)的最左前缀,也就是不符合最左原则

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。