Mysql中三星索引

  • Post author:
  • Post category:mysql


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%,所以在大部分的情况下,会先考虑第一颗星,但会根

据业务情况调整这两颗星的优先度。



版权声明:本文为Zhuxiaoyu_91原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。