什么是索引

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

索引的数据结构

哈希表

哈希表是一种以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. [leetcode] 929. Unique Email Addresses (easy)

    统计有几种邮箱地址. 邮箱名类型:local@domain 规则:1. local中出现"."的,忽略. a.bc=abc 2. local中出现"+"的,+以 ...

  2. [leetcode] 7. Reverse Integer (easy)

    原题 水题 唯一注意的点就是数字溢出 class Solution { public: int reverse(int x) { long long MAX = ((long long)1 <& ...

  3. Flink 灵魂两百问,这谁顶得住?

    Flink 学习 https://github.com/zhisheng17/flink-learning 麻烦路过的各位亲给这个项目点个 star,太不易了,写了这么多,算是对我坚持下来的一种鼓励吧 ...

  4. 全文检索方案Elasticsearch【Python-Django 服务端开发】

    更详细请看 https://www.elastic.co/cn/ 1. 全文检索和搜索引擎原理 商品搜索需求 当用户在搜索框输入商品关键字后,我们要为用户提供相关的商品搜索结果. 商品搜索实现 可以选 ...

  5. 对JAVA Bean使用PropertyDescriptor反射调用JAVA方法低耦合

    对于符合JAVA Bean规范的bean,调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性. public void g ...

  6. 夯实Java基础(一)——数组

    1.Java数组介绍 数组(Array):是多个相同类型元素按一定顺序排列的集合. 数组是编程中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常我们可以通过数组元素的索引来访问 ...

  7. 前端笔记之微信小程序(四)WebSocket&Socket.io&摇一摇案例&地图|地理位置

    一.WebSocket概述 http://www.ruanyifeng.com/blog/2017/05/websocket.html Workerman一款开源高性能异步PHP socket即时通讯 ...

  8. RocketMq中网络通信之服务端

    一,Broker服务端入口(NettyServer端) 首先RocketMq网络通信采用的Netty通信.服务端主要集中在Broker中.我们先看一下Broker的启动类BrokerStartup 显 ...

  9. 高性能MySQL之基础架构

    一.背景 为什么我们需要先学习MYSQL的基础架构先呢? 原因很简单,当我们需要了解一件事物的时候,我们只有站在宏观的层面,才能层层剥丝抽茧的去理解问题.举个例子,我们要看一个框架的源码,一开始就想进 ...

  10. 19 个 JavaScript 编码小技巧

    这篇文章适合任何一位基于JavaScript开发的开发者.我写这篇文章主要涉及JavaScript中一些简写的代码,帮助大家更好理解一些JavaScript的基础.希望这些代码能从不同的角度帮助你更好 ...