美文网首页
MySQL中的索引——概念篇

MySQL中的索引——概念篇

作者: 黑色小核 | 来源:发表于2017-04-23 09:20 被阅读1215次

使用索引的目的

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

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

索引的原理

索引的主要思想是将数据分段,从而减少查询时的无效数据,提高查询效率。比如有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

相关文章

  • MySQL中的索引——概念篇

    使用索引的目的 使用索引的目的是提高数据库查询的效率。索引是怎么提高数据库查询的效率的呢?举个通俗的例子,查字典。...

  • Mysql之索引的基本概念语法

    1.Mysql中索引的概念 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检...

  • MySQL和ES的索引对比

    [toc] MySQL索引实现 在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,...

  • MySQL之初识索引(下)

    在上一篇文章中,介绍了InnoDB索引的数据结构模型,现在聊聊跟MySQL索引有关的概念。 在下面这个表 T 中,...

  • MySQL索引实现及优化

    MySQL索引实现 在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论...

  • MySQL深入浅出索引(下)

    在上一篇文章中,我和你介绍了 InnoDB 索引的数据结构模型,今天我们再继续聊聊跟 MySQL 索引有关的概念。...

  • Laravel 中使用 ElasticSearch

    1️⃣ Elasticsearch 的基本概念: 索引 (index) 每个索引相当于 MySQL 中的 data...

  • 02-索引

    一、索引的概念 1、索引是什么 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据...

  • 索引优点和缺点

    概念 MySQL 官方对索引的定义为:索引(Index)是帮助 MySQL 高效获取数据的数据结构。可以得到索引的...

  • MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详

    有此可以看出此时,mysql使用的是行索引。 但是还有一个需要我们注意 MySQL中的锁概念 Mysql中不同的存...

网友评论

      本文标题:MySQL中的索引——概念篇

      本文链接:https://www.haomeiwen.com/subject/zoiezttx.html