MySQL中的索引——概念篇

使用索引的目的

使用索引的目的是提高数据库查询的效率。索引是怎么提高数据库查询的效率的呢?举个通俗的例子,查字典。数据库中的数据就好比新华字典中的词条,索引就是新华字典的目录。没有建立索引的数据库就好像被撕掉目录的新华字典,只能从头到尾一条一条地查询,效率极其低下。

为了能更快地查字典,哦不,是查询数据库,我们就需要为数据库建立索引。

索引的原理

索引的主要思想是将数据分段,从而减少查询时的无效数据,提高查询效率。比如有1000条数据,1到100分成第一段,101到200分成第二段,201到300分成第三段……这样查第250条数据,只要找第三段就可以了,一下子去除了90%的无效数据。

当然,上面只是主要思想,MySQL使用了更加具体的数据结构来实现索引。本文不对索引的数据结构展开讨论。

建立索引的几大原则

如何建立合适的索引,从而最大程度地优化查询效率是一件需要精心设计的事情。本节只介绍几个建立索引时须遵循的原则。

  1. 最左前缀匹配原则,非常重要的原则。mysql会一直向右匹配直到遇到范围查询><betweenlike就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。关于最左前缀匹配原则,在最左前缀匹配原则一节有详细说明。
  2. 尽量选择区分度高的列作为索引,区分度公式为count(distinct col)/count(*),即一列中内容不同的记录数占总记录数的比例。通过这个公式我们可以得到字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0。所以唯一索引的效率是最高的。在不是唯一键的时候,就要具体情况具体分析了,这也是索引设计的关键点之一。
  3. 索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,索引的数据结构中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
  4. 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
  5. 使用短索引。如果对串列进行索引,应该指定一个前缀长度,只要有可能就应该这样做 。
    例如,如果有一个 CHAR(200) 列,如果在前 10 个或 20 个字符内,多数值是惟一的,
    那么就不要对整个列进行索引。对前 10 个或 20 个字符进行索引能够节省大量索引空
    间,也可能会使查询更快。

最左前缀匹配原则

最左前缀使用场景是使用复合索引的时候。当使用复合索引时,如果想要索引有效,where之后的表达式就要满足最左前缀匹配原则。

我总结了一下最左前缀匹配的特点,就是从表达式最左边开始,到第一个范围查询结束,在这个闭区间内的字段应该是索引字段的最左前缀

最左前缀

在这里解释一下最左前缀,因为没有百度到感觉比较靠谱的解释,所以我在这里谈一下我的理解,仅供参考。

前缀应该不用解释了,学过英语的都该懂点。前缀加个就是左前缀了,表示从左边开始查找的前缀。但是,这个左只是表示查找的顺序是从左边开始,不是从右边开始,并没有说从哪一位开始,可能是第一位,也可能是第三位。这时候再加一个 就表示了从最左边开始。

比如复合索引是(a,b,d,c),那么查询时表达式的字段顺序为(a)、(a,b)、(a,b,d)、(a,b,d,c)的这些都是它的最左前缀,而(b)、(a,d)、(a,b,c)、(a,b,c,d)这些就不是。

关于MySQL的查询优化器

最左前缀的概念我们已经明白了,但是在MySQL中的情况又有点不同。比如我们发现,索引的顺序是(a,b,d,c),我们的查询条件是这样写的:where b=10 and c=16 and a=26 and d=0,从严格意义上来讲,这个顺序是不符合最左前缀匹配原则的,但是MySQL的确使用索引完成了查询。这是怎么回事呢?这是因为MySQL的查询优化器帮我们调整了查询条件的顺序。MySQL查询优化器会判断纠正一条sql语句该以什么样的顺序执行效率最高,最后才生成真正的执行计划。在有索引的情况下当然是利用索引查询顺序的效率最高咯,所以,MySQL查询优化器会最终以索引的顺序进行查询执行。

最左前缀匹配原则的原理

上面说了这么多的最左前缀的概念,那么我们到底为什么一定要符合最左前缀匹配原则呢?

因为复合索引只有第一个字段是绝对有序的,从第二个开始的字段都只是相对前一个字段有序,在全局范围内是无序的。只有满足最左前缀原则,才可以保证查询内容的有序,而有序又是索引使用的前提。

我们来看个例子,以该表的(name,cid)复合索引为例,它内部结构简单说就是下面这样排列的:

name cid
a 6
c 4
c 5
h 1
z 9

MySQL创建复合索引的规则是首先会对复合索引的最左边的,也就是第一个name字段的数据进行排序,在第一个字段的排序基础上,然后再对后面第二个的cid字段进行排序。其实就相当于实现了类似 order by name cid这样一种排序规则。

第一个name字段是绝对有序的,而第二字段就是无序的了。所以通常情况下,直接使用第二个cid字段进行条件判断是用不到索引的。

那么什么时候才能用到呢?当然是cid字段的索引数据也是有序的情况下才能使用咯,什么时候才是有序的呢?观察可知,当然是在name字段是等值匹配的情况下,cid才是有序的。发现没有,观察两个name名字为 ccid字段是不是有序的呢。从上往下分别是4 5。这也就是MySQL索引规则中要求复合索引要想使用第二个索引,必须先使用第一个索引的原因(最左前缀匹配原则)。

补充使用索引时的具体情况

更多使用索引的详细情况,可以参考最左前缀原理与相关优化

本文的参考资料

http://blog.jobbole.com/86594/

https://www.zhihu.com/question/36996520/answer/93256153

http://www.kancloud.cn/kancloud/theory-of-mysql-index/41857

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容