索引概念:

概念:索引是提高mysql查询效率的数据结构。总的一句话概括就是索引是一种提高查询效率的数据结构。

数据库查询是数据库的最主要功能之一。设计者们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化。

最基本的查询算法当然是顺序查找(linear search),这种复杂度为O(n)的算法在数据量很大时显然是糟糕的,好在计算机科学的发展提供了很多更优秀的查找算法,例如:有顺序查找、折半查找、快速查找等。

但是,每种查找算法都只能应用于特定的数据结构之上,例如顺序查找依赖于顺序结构,折半查找通过二叉查找树或红黑树实现二分搜索。

因此,在数据之外,数据库系统还维护着满足特定查找算法的数据结构。这种数据结构,就是索引

索引性能分析

目前,大多数数据库系统及文件系统都采用 B-Tree 或其变种 B+Tree 作为索引结构。B+ 树索引是 B+ 树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。

B+ 树是由二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree)逐步优化而来。

        有序数组、Hash索引、红黑树、二叉查找树、AVL树也可以作为数据结构也可以用来实现索引,但是文件系统以及数据库系统普遍采用B树或者B+树,这里结合各个索引的特点以及计算的组成原理来深入的分析。

但是,对于Mysql来说适合它的才是最好的查询,一方面要实现高效的查询,除了简单的条件查询,还要支持有序的高效索引的范围查询、分组。

有序数组在等值查询和范围查询性能都是非常好的,那为什么又不用有序数组作为索引呢?因为对于数组而言作为索引更新的成本太高,新增数据要把后面的数据都往后移一位,所以也不采用有序数组作为索引的底层实现。

hash是以key-value的形式进行存储,适合于等值查询的场景,查询的时间复杂度为O(1),因为hash储存并不是有序的,所以对于范围查询就可能要遍历所有数据进行查询,而且不同值的计算还会出现hash冲突,所以hash并不适合于做Mysql的索引。

另一方面就是除了查询的效率要高,还要有高效的读取数据效率(io),我们都知道计算机的随机磁盘io效率是非常低下的

B+树索引原理

在 B+Tree 中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储 key 值信息,这样可以大大加大每个节点存储的 key 值数量,降低 B+Tree 的高度。

在B+树的结构中,只在叶子节点存储数据,在非叶子节点中只存储的索引,在非叶子节点中可以有更大的空间储存更多的索引,这样B+树的出度d就可以大大的增加,从而降低的B+树的高度h,B树中一个节点的大小为一个page的大小,也就是一次IO的读取,h越小IO的次数就可以减少:dmax=floor(pagesize/(keysize+datasize+pointsize))

B+树的搜索过程:

 假设我们要搜索id为15的数据

  1. 根据根节点找到磁盘块 1,读入内存,一般根节点也会常驻内存,甚至可以省略一次磁盘IO操作。【磁盘 I/O 操作第 1 次】
  2. 比较id 15在区间28的左边,于是根据p1找到磁盘2。
  3. 将磁盘2读入内存,查找结果15在(10,17)之间。【磁盘 I/O 操作第 2 次】
  4. 然后根据磁盘2的指针p2找到磁盘块5,读入内存。【磁盘 I/O 操作第 3 次】
  5. 最后根据id=15找到对应的数据,返回结果。

根据上面的查找只需要至多三次的磁盘IO就可以找到对应的数据。从上面的B+树的原理图中非叶子节点构成了类似于一个一个目录一样,也可以叫做索引页,最后找到叶子结点的数据.

MyISAM

在MyISAM储存引擎中,数据和索引文件是分开储存的,Myisam 的存储文件有三个,后缀名分别是 .frm、.MYD、MYI,其中 .frm 是表的定义文件,.MYD 是数据文件,.MYI 是索引文件。

Myisam 只支持表锁,且不支持事务。Myisam 由于有单独的索引文件,在读取数据方面的性能很高 。

Myisam 也是B+树结构,但是MyISAM索引的叶子节点的数据保存的是行数据的地址。因此,MyISAM中索引检索的算法首先在索引树中找到行数据的地址,然后根据地址找到对应的行数据。

可以看出MyISAM的索引文件仅仅保存数据记录的地址。主键索引和辅助索引,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的如下图:

InnoDB

在InnoDB中,数据和索引文件是合起来储存的,如图所示,InnoDB 的存储文件有两个,后缀名分别是 .frm 和 .idb,其中 .frm 是表的定义文件,而 idb 是数据文件。

如果给另一个字段指定为普通索引,则普通索引树的结构如下图所示:

所以,当查询不是按照主键查询时候就会先在辅助索引树上先找到主键的值,然后再到主索引树找到对应的行数据的值,这叫做回表,回表降低了表的查询效率。

Mysql索引种类

Mysql中索引的种类也不是很多,不同类型的索引有不同的作用,索引的作用相互之间也存在交叉关系,Mysql中索引主要分为以下几类:

  1. 「主键索引」(PRIMARY KEY):主键索引一般都是在创建表的时候指定,「一个表只有一个主键索引」,特点是「唯一、非空」。
  2. 「唯一索引」(UNIQUE):唯一索引具有的特点就是唯一性,可以在创建表的时候指定,也可以在创建表后创建。
  3. 「普通索引」(INDEX):普通索引唯一的作用就是加快查询。
  4. 「组合索引」( INDEX):组合索引是创建一个「多个字段的索引」,这个概念是相对于上上面的单列索引而言,组合索引查询遵循「最左前缀原则」。
  5. 「全文索引」(FULLTEXT):全文索引是针对一些大的「文本字段」创建的索引,也称为「全文检索」。
  6. 「聚簇索引」和「非聚簇索引」:聚簇索引和非聚簇索引的概念比上面的概念要大,属于包含和被包含的关系。例如:InnoDB中主键索引使用的就是聚簇索引。

查看一个表的所有索引,可以执行下面的sql来查看:-====================>show index from 表名

主键索引

主键索引在InnoDB存储引擎中是最常见的索引类型,一个表都会有一个主键索引,它索引的字段不允许为空值,并且唯一。

一般是在创建表的时候,可以通过RIMARY KEY指定主键索引,在InnoDB存储引擎中,若是创建表的时候没有主观创建主键索引,Mysql就会看表中是否有唯一索引,有,就会指定「非空的唯一索引」为主键索引

若是没有唯一索引,就会默认生成一个6byte空间的自动增长主键作为主键索引,可以通过select _rowid from 表名查询的是对应的主键值.。

精通 MySQL 索引的更多相关文章

  1. 精通MySQL之索引篇,这篇注重练习!

    老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南.这份指南把大数据的[基础知识][框架分析][源码理解]都用自己的话描述出来,让 ...

  2. (转)MySQL索引原理及慢查询优化

    转自美团技术博客,原文地址:http://tech.meituan.com/mysql-index.html 建索引的一些原则: 1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到 ...

  3. MySQL索引原理及慢查询优化 转载

    原文地址: http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能 ...

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

    add by zhj:这是美团点评技术团队的一篇文章,讲的挺不错的. 原文:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰 ...

  5. 【转载】MySQL索引原理及慢查询优化

    原文链接:美团点评技术团队:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型 ...

  6. 干货:MySQL 索引原理及慢查询优化

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...

  7. 俗话:MySQL索引

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位 ...

  8. MySQL索引原理及慢查询优化(转自:美团tech)

    背景 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会 ...

  9. MySQL索引原理及慢查询优化-来自美团网的技术blog(写的深入浅出)

    MySQL索引原理及慢查询优化 转:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首 ...

随机推荐

  1. day13 iptables防火墙

    day13 iptables防火墙 一.防火墙的概述 1.什么是防火墙 防止恶意流量访问的软件就叫做防火墙. 2.防火墙的种类 软件防火墙:firewalld.iptables 硬件防火墙:F5 fi ...

  2. 零基础学习java------21---------动态代理,java8新特性(lambda, stream,DateApi)

    1. 动态代理 在一个方法前后加内容,最简单直观的方法就是直接在代码上加内容(如数据库中的事务),但这样写不够灵活,并且代码可维护性差,所以就需要引入动态代理 1.1 静态代理实现 在讲动态代理之前, ...

  3. Docker学习(一)——安装docker

    Suse12上安装docker   对于suse13.2之后的版本,因为docker已经被添加到了suse仓库中,直接使用sudo zypper install docker即可.   suse12不 ...

  4. JavaIO——System对IO的支持、序列化

    1.系统类对IO的支持 在我们学习PriteWriter.PrintStream里面的方法print.println的时候是否观察到其与我们之前一直使用的系统输出很相似呢?其实我们使用的系统输出就是采 ...

  5. 'this' pointer in C++

    The 'this' pointer is passed as a hidden argument to all nonstatic member function calls and is avai ...

  6. js中获取url参数

    function getUrlVars() { var vars = [], hash; var hashes = window.location.href.slice(window.location ...

  7. 动态规划系列(零)—— 动态规划(Dynamic Programming)总结

    动态规划三要素:重叠⼦问题.最优⼦结构.状态转移⽅程. 动态规划的三个需要明确的点就是「状态」「选择」和「base case」,对应着回溯算法中走过的「路径」,当前的「选择列表」和「结束条件」. 某种 ...

  8. 基于Annotation(注解)的装配

    一.常用注解 1.@Component 是一种通用注解,可用于任何Bean 2.@Repository 通常用于注解DAO层类,即持久层 3.@Service 通常用于注解Service类,即服务层 ...

  9. 【C/C++】string的长度

    一般用 s.length() s.size() 两种 size也可以用于vector string和vector的区别 string输入直接cin vector一般类似压栈pushback 输入一般是 ...

  10. 【阿菜做实践】利用go语言写一个简单的Pow样例

    本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简单demo.开发IDE用的是JB Golang. 整个项目的文件结构如下: PoWdem ...