细说MySql索引原理
MySQL索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql。如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的,如果我想找到m开头的单词呢?或者ze开头的单词呢?是不是觉得如果没有索引,这个事情根本无法完成?
索引类型
MySQL目前主要有以下几种索引类型:
1.普通索引
2.唯一索引
3.主键索引
4.组合索引
5.全文索引
索引创建
普通索引
这是最基本的索引,它没有任何限制。创建方式:
CREATE INDEX indexName ON table_name (column_name)
唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。创建方式:
CREATE UNIQUE INDEX indexName ON table_name (username(length))
主键索引
是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引:
CREATE TABLE `table_name` (`id` int(11) NOT NULL AUTO_INCREMENT ,`title` char(255) NOT NULL ,PRIMARY KEY (`id`));
组合索引
指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合:
ALTER TABLE `table_name` ADD INDEX name_city_age (name,city,age);
全文索引
全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。
创建方式:
CREATE FULLTEXT INDEX index_content ON table_name(content)
索引的数据结构
首先,数据库索引使用树来存储,因为树的查询效率高,而且二叉查找树还可以保持数据的有序。
那么索引为什么没有使用二叉树来实现呢?
其实从算法逻辑上讲,二叉查找树的查找速度和比较次数都是最小的,但是从Mysql的角度讲,我们不得不考虑一个现实问题:磁盘IO。
当我们利用索引查询的时候,不可能把整个索引全部加载到内存,只能逐一加载每个磁盘页,磁盘页对应索引树的节点。
那么Mysql衡量查询效率的标准就是磁盘IO次数。
如果我们利用二叉树作为索引结构,那么磁盘的IO次数和索引树的高度是相关的。
那么为了提高查询效率,就需要减少磁盘IO数。为了减少磁盘IO的次数,就需要尽量降低树的高度,需要把原来“瘦高”的树结构变的“矮胖”,树的每层的分叉越多越好,因此b+树正好符合我们的要求。
b+树
b+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。
我们先来看看b+树存储结构,比如有一张用户表(user),数据如下:
| id | 其他字段 |
| 3 | |
| 5 | |
| 9 | |
| 10 | |
| 13 | |
| 15 | |
| 28 | |
| 29 | |
| 36 | |
| 60 | |
| 75 | |
| 79 | |
| 91 | |
| 95 |
相应b+树,如下图:

如上图,这就是一个b+树。其中浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、91、95。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。
b+树的查找过程
比如,查询id为29的记录:
select * from where id=29
如上图所示,如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。
真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。
缺点
上面说明都是索引的优点,索引同样的也存在缺点:
1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行insert、update和delete。因为更新表时,不仅要保存数据,还要保存一下索引文件。
2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会增长很快。
3.索引只是提高效率的一个因素,如果有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
最后
MySQL改善查询性能改善的最好方式,只有我们明白索引的原理,才能更合理地使用索引!
文章首发于公众号【编程乐趣】,欢迎大家关注。

细说MySql索引原理的更多相关文章
- Mysql高手系列 - 第22篇:深入理解mysql索引原理,连载中
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第22篇. 背景 使用mys ...
- MySQL索引原理及慢查询优化
原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...
- (转)MySQL索引原理及慢查询优化
转自美团技术博客,原文地址:http://tech.meituan.com/mysql-index.html 建索引的一些原则: 1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到 ...
- MySQL索引原理及慢查询优化 转载
原文地址: http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能 ...
- MySQL索引原理及慢查询优化(转)
add by zhj:这是美团点评技术团队的一篇文章,讲的挺不错的. 原文:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰 ...
- 【转载】MySQL索引原理及慢查询优化
原文链接:美团点评技术团队:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型 ...
- MySQL索引原理与慢查询优化
索引目的 索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql.如果没有索引,那么你可能需要把所有单词看一遍才 ...
- 干货:MySQL 索引原理及慢查询优化
MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...
- MySQL索引原理及慢查询优化(转自:美团tech)
背景 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会 ...
- 知识点:Mysql 索引原理完全手册(2)
知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 八. 联合索引与覆盖索引 ...
随机推荐
- 什么是API?(详解)
编程资料时经常会看到API这个名词,网上各种高大上的解释估计放倒了一批初学者.初学者看到下面这一段话可能就有点头痛了. API(Application Programming Interface,应用 ...
- 【图文教程】云服务器上,Linux安装VSFTPD组件及遇到的问题
服务器做迁移,从AXX云迁移到Txx云上,迁移的话,需要把图片服务器也迁移过去.之前使用的是VSFTPD这次也还用这个吧.这里就记录下FTP服务器安装及遇到的问题. 1:安装VSFTP组件 使用yum ...
- 《linux实用指令积累》持续更新。。。
一.远程服务器文件拷贝 1.1.scp scp /home/a.txt root@127.0.0.1:/home/ 1.2.sshpass(适用于脚本调用,直接指定密码) 1.2.1.安装sshpas ...
- ansible部署jdk source /etc/profile 不起作用?
问题: ansible调用playbook远程mvn执行打包时发现执行出错,找不到JAVA_HOME.我们的exporter JAVA_HOME=/usr/java/jdk1.8.0写在/etc/pr ...
- EF Core – ExecuteUpdate and ExecuteDelete (Bulk updates 批量更新和删除)
前言 EF Core 在 SaveChanges 之后会一句一句的去更新和删除数据. 有时候这个效率是很差的. 而 SQL 本来就支持批量更新和删除, 所以是 EF Core 的缺失. 在 EF Co ...
- P1543 [POI2004] SZP 题解
P1543 [POI2004] SZP 题解 传送门. 题目简述 有 \(n\) 个人,每个人都会监视另一个人,要求选出尽可能多的同学,使得选出的每一名同学都必定会被监视到.且选出的同学不可再监视其他 ...
- Linux_Bash_Shell_索引数组和关联数组及稀疏数组
1. 索引数组 一.什么是索引数组? 所谓索引数组就是普通数组,以整数作为数组元素的索引下标. 二.实例. 备注: (a)使用-a选项定义索引数组,使用一对小括号()定义数组中的元素列表. (b)索引 ...
- 【赵渝强老师】什么是Spark SQL?
一.Spark SQL简介 Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作用. 为什么要学习Spark SQL? ...
- Android libusb
一.环境:配置NDK环境 1.下载libusb源码: https://github.com/libusb/libusb/releases,如下图所示 2.删除一些和Android平台无关的文件,删除后 ...
- 推荐一款轻量级 eBPF 前端工具 ply
1 Overview ply 是 eBPF 的 front-end 前端工具之一,专为 embedded Linux systems 开发,采用 C 语言编写,只需 libc 和内核支持 BPF 就可 ...