1.概念
三星索引概念是在《Rrelational Database Index Design and the optimizers》 一书
The index earns one star if it places relevant rows adjacent to each other,
a second star if its rows are sorted in the order the query needs,
and a final star if it contains all the columns needed for the query.
索引将相关的记录放到一起则获得一星;
如果索引中的数据顺序和查找中的排列顺序一致则获得二星;
如果索引中的列包含了查询中需要的全部列则获得三星。
2.示例
达成三星索引
现在有表
create table student(
age int,
fname varchar(10),
sname varchar(10),
sex int,
weight int,
school varchar(10));
建立索引
create index idx_stu on student(school,fname,sname,age);
对于下面的SQL而言,这是个三星索引
select age,sname from student where fname =’xx’ and school =’yy’ order by sname;
分析如下:
第一颗星:所有等值谓词的列,是组合索引的开头的列,可以把索引片缩得很窄,符合。
第二颗星:order by的sname字段在组合索引中且是索引自动排序好的,符合。
第三颗星:select中的age字段、sname字段在组合索引中存在,符合。
达不成三星索引
现在有表
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(100) DEFAULT NULL,
`sex` int(11) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`c_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
SQL语句如下:
select user_name,sex,age from test where user_name like ‘test%’ and sex =1
ORDER BY age
如果我们建立索引(user_name,sex,age):
第三颗星,满足
第一颗星,满足
第二颗星,不满足,user_name 采用了范围匹配,sex 是过滤列,此时age 列无法保证有序的。
上述我们看到,此时索引(user_name,sex,age)并不能满足三星索引中的第二颗星(排序)。
于是做如下修改,建立索引(sex, age,user_name):
第一颗星,不满足,只可以匹配到sex,sex选择性很差,意味着是一个宽索引片,
第二颗星,满足,等值sex 的情况下,age是有序的,
第三颗星,满足,select查询的列都在索引列中,
对于索引(sex,age,user_name)我们可以看到,此时无法满足第一颗星,窄索引片的需求。
以上2个索引,都是无法同时满足三星索引设计中的三个需求的,我们只能尽力满足2个。
而在多数情况下,能够满足2颗星,已经能缩小很大的查询范围了,具体最终要保留
那一颗星(排序星 or 窄索引片星),这个就需要看查询者自己的着重点了,无法给出
标准答案。
这三颗星,哪颗最重要?第三颗星。因为将一个列排除在索引之外可能会导致很多磁盘
随机读(回表操作)。第一和第二颗星重要性差不多,可以理解为第三颗星比重是50%,
第一颗星为27%,第二颗星为23%,所以在大部分的情况下,会先考虑第一颗星,但会根
据业务情况调整这两颗星的优先度。