什么是索引

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

索引的数据结构

哈希表

哈希表是一种以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. RecycleView文字吸顶,点击吸顶布局刷新数据

    实现效果 需求 Recycle有一个头布局,可以跟随列表进行滑动 点击头布局之后可以重新加载列表数据 随着头布局的消失,留下一个可点击的布局(该布局在头布局中) 效果类似下图: 淘宝的商品列表,随着我 ...

  2. linux初学者-SElinux篇

    linux初学者-SElinux篇 SElinux是强制访问控制(MAC)安全系统,是linux历史上最杰出的新安全系统.对于linux安全模块来说,SElinux的功能是最全面的,测试也是最充分的, ...

  3. Spring方法级别数据校验:@Validated + MethodValidationPostProcessor

    每篇一句 在<深度工作>中作者提出这么一个公式:高质量产出=时间*专注度.所以高质量的产出不是靠时间熬出来的,而是效率为王 相关阅读 [小家Java]深入了解数据校验:Java Bean ...

  4. 第一章: 初识Java

    计算机程序:计算机为完成某些功能产生的一系列有序指令集合. Java技术包括:JavaSE(标准版) JavaEE(企业版) ---JavaME(移动版) 开发Java程序步骤:1.编写 2.编译 3 ...

  5. 输出单链表倒数第K个结点值

    #include<iostream>using namespace std;#include<malloc.h>#include<stdio.h>typedef i ...

  6. CSDN Markdown 超链接

    CSDN Markdown 的超链接总是在当前页面打开新的链接,后来发现了一种可以在新窗口打开超链接的语法,如下: <a href="https://zh.wikipedia.org/ ...

  7. 使用log4net记录ABP日志

    demo地址:ABP.WindowsService 该文章是系列文章 基于.NetCore和ABP框架如何让Windows服务执行Quartz定时作业 的其中一篇. 参考:https://aspnet ...

  8. C++实现反射

    之前碰到过一个问题,C++中如何通过一个字符串生成一个类. C++是不支持通过类名称字符串”ClassXX”来生成对象的,也就是说我们可以使用 new ClassXX 来生成对象,但是不能通过 new ...

  9. 使用Java 编写FTP中的长传文件和下载文件

    实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式,),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方法:通过JDK自带的API实现 ...

  10. Netty源码分析-- ThreadLocal分析(九)

    为了更好地探讨Netty的内存模型,后面会用到,这里我还是决定跟大家一起看下ThreadLocal和FastThreadLocal的源码,有的时候我们在看源码的时候会一层层的遇到很多之前没有看过的内容 ...