MySQL(二):快速理解MySQL数据库索引
索引
基本概念:索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。
数据结构
- Tree 指的是 Balance Tree,也就是平衡树。平衡树是一颗查找树,并且所有叶子节点位于同一层。
- B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具有 B Tree 的平衡性,并且通过顺序访问指针来提高区间查询的性能。
- 在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。

基本原理
- 进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。
- 插入删除操作会破坏平衡树的平衡性,因此在进行插入删除操作之后,需要对树进行分裂、合并、旋转等操作来维护平衡性。
红黑树
红黑树等平衡树也可以用来实现索引,但是文件系统及数据库系统普遍采用 B+ Tree 作为索引结构,这是因为使用 B+ 树访问磁盘数据有更高的性能。
- B+ 树有更低的树高:平衡树的树高 O(h)=O(logdN),其中 d 为每个节点的出度。红黑树的出度为 2,而 B+ Tree 的出度一般都非常大,所以红黑树的树高 h 很明显比 B+ Tree 大非常多。
- 磁盘访问原理:操作系统一般将内存和磁盘分割成固定大小的块,每一块称为一页,内存与磁盘以页为单位交换数据。数据库系统将索引的一个节点的大小设置为页的大小,使得一次 I/O 就能完全载入一个节点。
如果数据不在同一个磁盘块上,那么通常需要移动制动手臂进行寻道,而制动手臂因为其物理结构导致了移动效率低下,从而增加磁盘数据读取时间。B+ 树相对于红黑树有更低的树高,进行寻道的次数与树高成正比,在同一个磁盘块上进行访问只需要很短的磁盘旋转时间,所以 B+ 树更适合磁盘数据的读取。 - 磁盘预读特性:为了减少磁盘 I/O 操作,磁盘往往不是严格按需读取,而是每次都会预读。预读过程中,磁盘进行顺序读取,顺序读取不需要进行磁盘寻道,并且只需要很短的磁盘旋转时间,速度会非常快。并且可以利用预读特性,相邻的节点也能够被预先载入。
索引分类
B+树索引
- 是大多数 MySQL 存储引擎的默认索引类型。
- 因为不再需要进行全表扫描,只需要对树进行搜索即可,所以查找速度快很多。
- 因为 B+ Tree 的有序性,所以除了用于查找,还可以用于排序和分组。
- 可以指定多个列作为索引列,多个索引列共同组成键。
- 适用于全键值、键值范围和键前缀查找,其中键前缀查找只适用于最左前缀查找。如果不是按照索引列的顺序进行查找,则无法使用索引。
- InnoDB 的 B+Tree 索引分为聚簇索引(主索引)和非聚簇索引(辅助索引)。
- 唯一索引:主键就是一种特殊的唯一索引,唯一索引允许null值,但主键列不允许为null值,一张表最多建议一个主键
哈希索引
- 哈希索引能以O(1)时间进行查找,但是失去了有序性特点InnoDB
- 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。
全文索引
- MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。
- 查找条件使用 MATCH(clo1,clo2..) AGAINST(value),而不是普通的 WHERE。全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。
- InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
FULLTEXT (clo1,clo2)只有建立的全文索引的列可以进行全文索引
索引优化
独立的列
进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引
多列索引
在需要使用多个列作为条件进行查询时,使用多列索引比使用多个单列索引性能更好。
列如下面的语句中可以将actor_id和film_id设置多列索引
SELECT film_id, actor_ id FROM sakila.film_actor
WHERE actor_id = 1 AND film_id = 1;
索引列的顺序
索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,每个记录的区分度越高,查询效率也越高。
让选择性最强的索引列放在最前面
输入语句:
SELECT COUNT(DISTINCT addr_id)/COUNT(*) AS addr_id_selectivity,
COUNT(DISTINCT user_id)/COUNT(*) AS user_id_selectivity,
COUNT(*)
FROM user_address;
结果:
addr_id_selectivity:1.0000
user_id_selectivity:0.1250
count(*):64
从上述结果分析:主键是唯一的,user_id会有重复,所以写sql语句时,主键应该放在最前面
这样可以逐个分析对应的索引
前缀索引
- 对于 BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符。
- 前缀长度的选取需要根据索引选择性来确定。某些列,一般是字符串类型,很长,全部作为索引大大增加存储空间,索引也需要维护,对于长字符串,又想作为索引列,一个可取的办法就是取前一部分(前缀),代表一整列作为索引串。
- 如何确保这个前缀能代表或大致代表这一列?所以mysql中有个概念是索引的选择性,是指索引中不重复的值的数目(也称基数)与整个表该列记录总数(#T)的比值,比如一个列表(1,2,2,3),总数是4,不重复值数目为3,选择性为3/4,因此选择性范围是[1/#T, 1],这个值越大,表示列中不重复值越多,越适合作为前缀索引,唯一索引(UNIQUE KEY)的选择性是1。
MySQL性能优化神器Explain使用分析

- Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explain 结果来优化查询语句。
- select_type : 查询类型,有简单查询、联合查询、子查询等
- key : 使用的索引
- rows : 扫描的行数
总结
- 数据库只做两件事情:存储数据、检索数据。而索引是在你存储的数据之外,额外保存一些路标(一般是B+树),以减少检索数据的时间。所以索引是主数据衍生的附加结构。
- 一张表可以建立任意多个索引,每个索引可以是任意多个字段的组合。索引可能会提高查询速度(如果查询时使用了索引),但一定会减慢写入速度,因为每次写入时都需要更新索引,所以索引只应该加在经常需要搜索的列上,不要加在写多读少的列上。
- 多使用explain对语句进行索引分析,任何理论都是建立在实际的分析基础上,explain语句关注那几个关键词即可。盲目的加索引并不是好的,有时候索引反而成为拖慢我们系统运行速度的源头.优化索引其实就两件事,第一找到区别度大的列,第二看生产的查询场景是否有用到这个列,加上索引用explain分析,看是否会比不加上索引性能提升更快
MySQL(二):快速理解MySQL数据库索引的更多相关文章
- 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效
数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...
- mysql的limit性能,数据库索引问题,dblog问题
mysql的limit性能,数据库索引问题,dblog问题,redis学习 继续学习. dblog实际上是把日志记录在另一个数据库里面. 问题1: 一张表定义了5个索引,但是sql语句中用到了3个有索 ...
- 通过mysql命令行理解mysql
引言:工具不可谓给我们的生活带来了便利,但有些时候我们却忘记了事物本身的意义.在大多数人都在追捧甚至是盲从各种各样的工具有多先进的时候,你是否有反思过:你目前是否有使用它的资格. 假设你学会了使用一款 ...
- 快速理解mysql主从,主主备份原理及实践
感谢大家在上一篇 学一点Git--20分钟git快速上手 里的踊跃发言.这里再次分享干货, 简单介绍mysql双机,多机异地热备简单原理实战. 双机热备的概念简单说一下,就是要保持两个数据库的状态自动 ...
- 学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践
双机热备的概念简单说一下,就是要保持两个数据库的状态 自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一致. 这样做的好处多. 1. 可以做灾备,其中一个坏了可以切换 ...
- 分析MySQL中哪些情况下数据库索引会失效
要想分析MySQL查询语句中的相关信息,如是全表查询还是部分查询,就要用到explain. 一.explain 用法:explain +查询语句. id:查询语句的序列号,上面图片中只有一个selec ...
- 【mysql】 快速搞定数据库迁移
工具:navicat for mysql
- 【MySQL】深入理解MySQL锁和事务隔离级别
先看个小案例: 话不多说,上案例,先创建一个表 mysql> CREATE TABLE IF NOT EXISTS `account`( `id` INT UNSIGNED AUTO_INCRE ...
- python Mysql (二)
Mysql (二) 一. 事务 a.数据库开启事务命令 1 2 3 4 #start transaction 开启事务 #Rollback 回滚事务,即撤销指定的sql语句(只能回退insert de ...
随机推荐
- mongodb查询前10条
mongo可以通过时间或者通过id来判断上一条记录或者下一条记录,我是通过id 前10条 db.数据库名称.find({ '_id': { '$lt': ids } }).sort({_id: -1} ...
- Linux三剑客grep、awk、sed
何为Linux三剑客? 第一个剑客是 grep,grep 会根据正则表达式查找相关内容并打印对应的数据. 第二个剑客是 awk,awk 的名字来源于三个作者的名字简称,它可以根据定位到的数据行处理其中 ...
- svn学习与应用
先来认识下svn svn是之前公司一直在用的代码版本控制系统,采用了分支管理系统.顾名思义,可以对代码的版本做系统化管理.通俗讲就是可用于多个人共同开发同一个项目,实现共用资源的目的. 开发同学使用s ...
- MindSpore手写数字识别初体验,深度学习也没那么神秘嘛
摘要:想了解深度学习却又无从下手,不如从手写数字识别模型训练开始吧! 深度学习作为机器学习分支之一,应用日益广泛.语音识别.自动机器翻译.即时视觉翻译.刷脸支付.人脸考勤--不知不觉,深度学习已经渗入 ...
- 用了Dapper之后就不要再见到SqlConnection咯
一.背景 前几天看公司一个新项目的底层使用了dapper,大家都知道dapper是一个非常强大的半自动化orm,帮程序员解决了繁琐的mapping问题,用起来非常爽,但我还是遇到了一件非常不爽的事情, ...
- Django搭建示例项目实战与避坑细节
Django 开发项目是很快的,有多快?看完本篇文章,你就知道了. 安装 Django 前提条件:已安装 Python. Django 使用 pip 命令直接就可以安装: pip install dj ...
- PyQt(Python+Qt)学习随笔:QListWidget的addItem方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在QListWidget对象中,增加一个项的方法是调用addItem方法,addItem方法有2种重 ...
- 第14.16节 爬虫实战2:赠人玫瑰,手留余香! request+BeautifulSoup实现csdn博文自动点赞
写在前面:本文仅供参考学习,请勿用作它途,禁止转载! 在<第14.14节 爬虫实战准备:csdn博文点赞过程http请求和响应信息分析>老猿分析了csdn博文点赞处理的http请求和响应报 ...
- PyQt(Python+Qt)学习随笔:布局控件layoutStretch属性
在Qt Designer中布局控件有4个,分别是Vertical Layout(垂直布局).Horizontal Layout(水平布局).Grid Layout(网格布局).Form Layout( ...
- 自学linux——22.粘滞位的了解及使用
粘滞位的了解及使用 一.权限 1.文件的权限 r (read) :可读取该文件的实际内容w(write):可以编辑,新增或者修改该文件的内容(但不含删除该文件)x(execute):代表该文件可以被系 ...