MySQL索引之组合索引

1.概念


 对于某些业务情况,当单列索引满足不了现实的业务,为了提高搜索效率,就需要考虑运用于组合索引.

 组合索引:即一个索引包含多个列;


2. 添加索引

ALTER TABLE people ADD INDEX `index_name` ( `column1`,`column2`,`column3`);


3.测试

建立基于departID,doctorID,scheduledTime的组合索引,执行计划如下:



4.最左前缀索引失效问题


之前创建的IDX_MBScheding_Group的组合索引,相当于创建了(departID,doctorCode,scheduledTime)、(departID,doctorCode)、(departID,scheduledTime)这些列组合上的索引.但是因为"mysql组合索引最左前缀"(Leftmost Prefixing)的结果.则不存在(doctorID,scheduledTime)等这样的组合索引.


最左前缀索引有效与无效列表:

//The following queries can use the Leftmost Prefixing index:
//where后过滤字段可不按该排序
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309 and doctorCode = '0003' and ScheduledTime = 'SW'
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309 and doctorCode = '0003' 
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309 and ScheduledTime = 'SW'
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309
//The following queries cannot use the Leftmost Prefixing index at all:
select ID,ScheduledDate from TB_MB_Scheduling where doctorCode = '0003' and ScheduledTime = 'SW'
select ID,ScheduledDate from TB_MB_Scheduling where doctorCode = '0003'
select ID,ScheduledDate from TB_MB_Scheduling where ScheduledTime = 'SW'

 
 
 
 

不存在(doctorID,scheduledTime)等这样的组合索引:

从执行计划可以看出最左前缀索引已经失效,直接进行全表扫描

- 那么问题来了,创建的索引顺序与where语句后顺序是否需要一致呢?

     在满足最左前缀索引情况下,查看where语句后字段不同的排序后的执行计划,发现:创建组合索引时字段的排序与where语句后顺序是不需要一致的.


总结:最左前缀是不是失效其实就是取决于你创建索引时,哪个字段排在首位,只要你的搜索条件包含有排在首位的那个字段就能走创建的索引,即满足最左前缀.

比如:基于(departID,doctorID,scheduledTime)创建的索引IDX_MBScheding_Group,只要where含有过滤字段departID=XXX,无论过滤字段顺序先后,都走索引IDX_MBScheding_Group.

- 那么问题又来了,怎么才能确定合适的索引列顺序呢?


5.选择合适的索引列顺序

正确的顺序依赖于使用该索引的查询,并且同时需要考虑如何更好的满足排序和分组的需要(本小节只适合B-Tree索引;哈希或者其他类型的索引并不会像B-Tree索引一样按顺序存储数据)

不需要考虑排序和分组时,将选择性最高的列放在前面通常时很好的.这时候索引的作用只是用于优化where条件的查找.


以下面查询为例

select * from TB_MB_Scheduling where departID = 309 and doctorCode = '0003' and ScheduledTime = 'SW'

是应该创建一个(departID,doctorCode,scheduledTime)还是颠倒一下顺序?还是?


5.1 具体查询法


可以先跑一下来确定在这个表中值的分布情况,并确定哪个列的选择性更高.先查看各个where条件的分支对应的数据基数有多大:



所以应该把索引列doctorCode放在前面,因为对应的条件值doctorCode数量更小.然后根据doctorCode的条件值,查看对应的其他2列的选择性如何:


(注:查询结果根据你选定条件的具体值而定)


5.2 经验法


经验法则考虑的是全局基数和选择性.而不是具体的某个查询.



doctorCode的选择性更高,所以应该将其作为第一列.


       


参考来自:

1.<<高性能MySQL>>

2.http://blog.csdn.net/xtdhqdhq/article/details/17582779


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值