什么是索引

索引就好比是书的目录,可以显著提高数据库查询的效率。例如像一本很厚的书,在没有目录的情况下要查到你想要看的知识点,都不知要找到什么时候,但通过目录我们可以很快的查询到对应的内容。

索引的数据结构

哈希表

哈希表是一种以K-V值存储的数据结构,这样,我们只需要输入K值,就会很快得到需要的V值。K值经过哈希计算得出,这样避免不了哈希碰撞问题,解决的方法是当K值哈希后一样时,可以采用列表的形式存储相应的数据,在查询时再经过列表逐一比对得到V值。哈希表在等值查询的时候非常快,但会存在下面问题:
1、无法进行范围查询
2、无法利用索引进行排序
3、存在哈希碰撞问题,当哈希碰撞过于严重时很影响效率
4、不支持最左前缀

有序数组

有序数组可以很好的解决范围查询的问题,查询数据也可以用二分法很快的找到对应的值。但在中间插入一条数据时,需要把后面的数据都往后移,代价太大。

二叉搜索树

二叉搜索树每个节点最多只有两个子节点,并且左节点小于等于父节点,右节点大于父节点。这样很好解决了等值查询、范围查询、数据插入的问题。但因为只有两个节点,这样数据量很大的时候,会产生很高的层级,并且数据库中这些层级不全是存放在内存中的(内存只会存放一级,有时还会存放进二级)而是存放磁盘中。这样就造成了多次IO操作,严重影响性能。

B+树

在二叉搜索树的基础上进行优化,每个节点至多可以达到拥有1200个子节点,子节点按照顺序存放。显著减少IO操作。

主键索引和普通索引

InnoDB中每张表都有主键索引,且是根据主键顺序存放数据的,如果建表时未定义主键,则数据库会自己生成rowid当主键。主键索引又被称为 聚簇索引主键索引的B+树中的页子节点存储的是整行数据。
普通索引又称二级索引或非主键索引,在B+树中的页子节点存储的是主键值。在这样一个SQL(select b from t where a = 10)执行时,数据库会在a的索引表中查询a='xx'对应到的主键值,再用这个主键到主键索引中查询需要的数据,这个过程叫做回表操作。

覆盖索引与索引下推

上面提到一个sqlselect b from t where a = 10在执行时会进行回表操作,回表操作多查询一次主键索引树,影响了效率。那有没有什么办法可以避免呢?答案是建立个联合索引INDEX index_a_b (a, b),这样数据在查询时就直接拿到了需要的b字段的值,不需要再进行回表操作。例如查询主键sql也是不需要回表操作select id from t where a = 10。这个就是覆盖索引的概念了。

索引下推是MySQL 5.6引入的功能,指的是可以在遍历的过程中就对包含的字段先做判断,直接过滤掉不符合条件的数据,减少回表操作。

例如select * from t where a > 10 and a <20 and b = 'xx'
如果没有索引下推功能,这条语句的执行过程是这样的:
1、判断a是否大于10且小于20
2、如果步骤1不满足条件,则进行下一条记录。如果步骤1满足条件,则从a的索引树中取得对应的主键进行回表操作。
3、回表操作取得整行数据,取b的值判断是否等于'xx',如果是,取出数据。重复步骤1和步骤2,直至a大于等于20终止。
上面的执行过程中如果满足步骤1的数据有100条,但同时满足t.b = 'xx'的数据只有10条,数据库却需要进行回表100次。

在引入了索引下推后的执行过程变成:
1、判断a是否大于10且小于20
2、如果步骤1不满足条件,则进行下一条记录。如果步骤1满足条件,则继续判断b是否等于'xx'。如果不满足,而进行下一条记录,如果满足,则从a的索引树中取得对应的主键进行回表操作,取出数据。
3、重复步骤1和步骤2,直至a大于等于20终止。
在引入索引下推后,整个过程就只需要回表10次,大大减少了回表操作。

最左前缀原则

最左前缀原则指的是只要sql满足最左前缀,就可以利用索引进行高效的查询。最左前缀可以是联合索引的最左N个字段,也可以是字符串索引的最左M个字符。

例如在上面我们建立的联合索引INDEX index_a_b (a, b),这时候其实相当于对a建立了单独索引,可以使用select id from t where a = 10快速得查询到主键值,这个a是联合索引的最左第一个字段。但此时select id from t where b = '张'这条sql是不会走索引的。如果建立的联合索引是这样的INDEX index_b_a (b, a),那么后面一条sql会走索引,而a=10的查询那条反而不会走索引。
建立了INDEX index_b_a (b, a)的联合索引,这时进行select id from t where b lik '张%'查询时,也会利用了索引。但像b lik '%张%'b lik '%张'是不会走索引的,这就是最左前缀中的字符串索引的最左M个字符。

【MySQL】索引的更多相关文章

  1. 深入MySQL索引

    MySQL索引作为数据库优化的常用手段之一在项目优化中经常会被用到, 但是如何建立高效索引,有效的使用索引以及索引优化的背后到底是什么原理?这次我们深入数据库索引,从索引的数据结构开始说起. 索引原理 ...

  2. MySQL 索引

    MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是 ...

  3. MYSQL索引结构原理、性能分析与优化

    [转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...

  4. MySQL索引原理及慢查询优化

    原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...

  5. 【转】MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  6. [转]MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  7. MySQL索引类型总结和使用技巧以及注意事项

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable ...

  8. MySQL索引背后的数据结构及算法原理【转】

    本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...

  9. mysql索引总结----mysql 索引类型以及创建

    文章归属:http://feiyan.info/16.html,我想自己去写了,但是发现此君总结的非常详细.直接搬过来了 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基 ...

  10. Mysql 索引实现原理. 聚集索引, 非聚集索引

    Mysql索引实现: B-tree,B是balance,一般用于数据库的索引.使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度.而B+tree是B-tree的一个变种,My ...

随机推荐

  1. C++ Primer 第五版 一些遇到的注意点记录。

    第8章 8.2 p283 示例里有一句 ostream *old_tie = cin.tie(nullptr);//old_tie指向当前关联到cin的流 一开始不理解为什么不是无关联,查过tie() ...

  2. MyEclipse 2016 Stable 1.0破解教程

    一.下载所需文件 1. Windows最新版: MyEclipse 2016 Stable 1.0离线安装包(文件大小:1.52GB)--完整安装包,无需在线下载http://pan.baidu.co ...

  3. Spring:IOC本质分析探究

    IOC本质分析 分析实现 我们先用我们原来的方式写一段代码 . 先写一个UserDao接口 public interface UserDao { public void getUser(); } 再去 ...

  4. linux初学者-数据库管理MariaDB篇

    linux初学者-数据库管理MariaDB篇 MariaDB是一种数据库管理系统,是MySQL的一个分支,但是比MySQL更加优秀,可以说是MySQL的替代品.MariaDB使用的是SQL语句.下文将 ...

  5. google、谷歌浏览截图

    对于前端好用的浏览器---谷歌浏览器(没有插件)截取全屏很难受! 特备是前端,想截图下来,好好的量一下容器之前的尺寸(手动恼火) 对于程序员来说不一定需要插件,有很多大佬应该都知道, 小白记忆不好,每 ...

  6. rabbitMQ_routing(四)

    路由 本次我们将通过路由将信息发送到指定的队列中,将消息发送给指定的队列需要在转发器和队列之间建立一个routeKey 绑定 在以前的例子中,我们已经创建了绑定.你可能会记得如下代码: channel ...

  7. spring与actionMQ整合

    出处:http://www.cnblogs.com/leiOOlei/p/5075402.html 一.配置部分 ActiveMQ的安装这就不说了,很简单, 这个例子采用maven构建,首先看一下po ...

  8. TIJ读书笔记-第21章-并发

    一本Think in java,从去年6月份开始读,读了快一年了,也快读完了,然而回头想想,却好像什么也不记得了,好记性不如烂笔头,那就从现在开始记录一下吧.由于现在在读的是并发,那就先从这章开始吧. ...

  9. Shell基本语法---shell介绍

    简介 1. shell是在linux系统上高效运行的脚本语言 2. 主要用来开发一些实用的.自动化的小工具,而不是用来开发具有复杂业务逻辑的中大型软件 3. shell的基本命令也是linux操作系统 ...

  10. 原创:微信小程序开发要点总结

    废话不多少,下面是对我从开发微信小程序的第一步开始到发布的总结,觉得对您有帮助的话,可以赞赏下,以对我表示鼓励. 一:首先注册登录微信公众平台,这个平台很重要,以后查文档全在上面看.https://m ...