【MySQL】索引
什么是索引
索引就好比是书的目录,可以显著提高数据库查询的效率。例如像一本很厚的书,在没有目录的情况下要查到你想要看的知识点,都不知要找到什么时候,但通过目录我们可以很快的查询到对应的内容。
索引的数据结构
哈希表
哈希表是一种以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】索引的更多相关文章
- 深入MySQL索引
MySQL索引作为数据库优化的常用手段之一在项目优化中经常会被用到, 但是如何建立高效索引,有效的使用索引以及索引优化的背后到底是什么原理?这次我们深入数据库索引,从索引的数据结构开始说起. 索引原理 ...
- MySQL 索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是 ...
- MYSQL索引结构原理、性能分析与优化
[转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...
- MySQL索引原理及慢查询优化
原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...
- 【转】MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- [转]MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- MySQL索引类型总结和使用技巧以及注意事项
索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable ...
- MySQL索引背后的数据结构及算法原理【转】
本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...
- mysql索引总结----mysql 索引类型以及创建
文章归属:http://feiyan.info/16.html,我想自己去写了,但是发现此君总结的非常详细.直接搬过来了 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基 ...
- Mysql 索引实现原理. 聚集索引, 非聚集索引
Mysql索引实现: B-tree,B是balance,一般用于数据库的索引.使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度.而B+tree是B-tree的一个变种,My ...
随机推荐
- 【MySQL】(六)锁
开发多用户.数据库驱动的应用时,最大的一个难点是:一方面要最大程度地利用数据库的并发访问,另一方面还要确保每个用户能以一致的方式读取和修改数据.为此就有了锁(locking)的机制,同时这也是数据库系 ...
- ASP.NET Core MVC 之布局(Layout)
1.什么是布局 布局通常包含常见的用户界面元素,例如应用头,导航或菜单元素和页脚,如图: 常见的HTML结构(例如脚本和样式表)也经常被应用程序中许多页面使用.所有这些共享元素都可以在布局中定义,然后 ...
- 聊聊HTML5中的Web Notification桌面通知
有的时候我们会在桌面右下角看到这样的提示: 这种桌面提示是HTML5新增的 Web Push Notifications 技术. Web Notifications 技术使页面可以发出通知,通知将被显 ...
- web设计_3_可伸缩的导航栏
1. HTML5构建一个选项卡,需要<nav>标签包围一个无序列表,也可以添加role属性告诉辅助设备(如屏幕阅读器)这个元素所扮演的角色. 绝对不要基于图片的导航,对搜索引擎不友好,更新 ...
- Reporting报表开发知识合并[个人原创]
[个人原创] ,转发请声明原文链接 了解 a) SSRS全称 SQL Server Reporting Services,是依赖于数据库运行的,是微软开发的重量级别的BI产品 b) ...
- shiro 和 spring boot 的集成
1 添加依赖 使用 shiro-spring-boot-web-starter 在 spring boot 中集成 shiro 只需要再添加一个依赖 <dependency> <gr ...
- C# sql 批量插入数据库的语句
//执行DataTable数据导入 public static int UpdateDt(string strConn, DataTable dt) { try { string tablaName ...
- SSD+HDD 安装ubuntu16.04+win7双系统
本人电脑是联想天逸100 前段时间把光驱拆了加了一个128G的SSD 顺便把SSD装上了win7 机械硬盘500G放资料和一般软件之类的 后来想要用到ubuntu 就在官网下载ubuntu1 ...
- 章节十五、3-对象仓库、Page Factory实例应用
一.如何创建对象仓库 package pageclasses; import org.openqa.selenium.WebDriver; import org.openqa.selenium.Web ...
- 【Android】System.exit(0) 退出程序
许多 Android 应用程序都是连续点击两下返回键时退出程序,代码如下: private long exitTime = 0; @Override public boolean onKeyDown( ...