因什么需求,要创建‘联合索引’?最实际好处在于什么?如果是为了更快查询到数据,有单列索引不是ok了,为什么有‘联合索引’的存在?求经验丰富老手谈谈。
最后的答案我截取了Filix Suo第二个观点里一段话为答案,创建多列索引的意义就是为了‘减少io操作’。可能使用这个会相应失去什么,这个就有待大量测试考证了。
2013/11/25 23:37更新:
今天刚入手mariadb,结果在手册里翻到了一份多列索引结构的解释(嘿嘿,真开源果然不同),贴出来供大家参考:
https://mariadb.com/kb/en/index-condition-pushdown/
创建多列索引(列1,列2,列3)后的结构类似这样(index结构,附属列,附属列)
附属列可能直接跟在叶节点上,或单独存放(这个没有看到说明)...
附带可以说明单列索引就是多列索引一种形式,只不过没有附属列罢了。。。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
简单的说有两个主要原因:
如下的有a,b,c 三个key的table
如果我们
需要执行很多的类似于 select * from test where a=10, b>50, c>20
这类的组合查询 那么,我们可能需要创建 包含[a,b,c] 的联合索引,而单独的[a][b] [c]上的索引是不够的。
(可以把一个索引想象成 sorted list).创建了 (a,b,c)的索引相当于 按照a,b,c 排序(排序规则是
)
和分别 按a 排序 分别按b排序 分别按照c排序是不一样的。
其中 a b c 的顺序也很重要,有时可以是a c b,或者b c a等等。
如果创建 (a,b,c)的联合索引,查询效率如下:
参考 http://blog.csdn.net/lmh12506/article/details/8879916
我认为是为了更快的区分出相同数据,有很多数据要区分多个属性是否相同,所以用到联合索引
举例:
创建一张数据表
假设每个班有50名学生,一个年级有10个班,一所学校有4个年级,共有3所学校,那么总共会有6000名学生
若要查询出第2所学校3年级学生的姓名,SQL如下
SELECT studentName FROM student WHERE schoolId=2 AND gradeId=3
如果使用名为
s_g_s
的联合索引,那通过索引,MySQL可筛选掉大部分不满足查询条件的学生信息,在这个例子中,可筛掉5500条记录,这样MySQL只需回表查询剩余的500条记录即可得到结果。如果只使用schoolId上的单列索引,只能筛掉4000条记录,需回表扫描过滤剩余的2000条记录才能得到结果,从数量上看差了一个数量级。性能自然不佳。
若要查询出第2所学校3年级学生的姓名并按照studentId倒排,SQL如下
SELECT studentName FROM student WHERE schoolId=2 AND gradeId=3 ORDER BY studentId DESC
这条SQL若没有多列索引,在较大数据量下性能会很差。但有了
s_g_s
索引,排序可以在索引上直接完成,不用MySQL取回记录后,再在内存或者磁盘上进行一次排序。性能提升很大。若要查询出第2所学校3年级学生的studentId,SQL如下
SELECT studentId FROM student WHERE schoolId=2 AND gradeId=3
对于这条查询,
s_g_s
索引包含所有需要查询的字段的值,MySQL根本不需要再去读取表中的记录,直接全部在索引上完成,这是性能最高的一种索引,通常称为“覆盖索引”。这个例子有点“简陋”,但还是可以说明一些问题。
综上,在实际项目中,
- 联合索引的使用要远多于单列索引。
- 联合索引使用正确对性能提升很有帮助。
- 怎么加索引,把哪些列加索引,加几个索引都是需要根据项目中使用到的SQL及数据表中数据的分布、数据的区分度去衡量的。
- 使用MySQL explain工具来解析SQL查询执行计划。
- 推荐看下这本书:《高性能MySQL》
创建多列索引的意义就是为了‘减少io操作
在mysql5.6版本之前大部分情况是不行的,即使你创建的多列索引,但是你的sql写的不对的话,用到的往往是第一列索引。
建议你去看看mysql的5.6新特性ICP。
再给你推荐一篇博文,能够较好的理解为什么会这样
http://hedengcheng.com/?p=577