在我之前的一篇文章中,有引用一个讨论用Hash还是Tree的问题,DB中关于查找类数据结构,除了树,还有Hash(HashMap,HashSet)。

存储数据结构之争

B+树主要是照顾磁盘IO这种特殊的性质应运而生的;然而在内存够多够大时,Hash某些时候比Tree结构有用得多。

但是Hash做索引的缺点也非常明显:

1,Hash冲突造成的散列不均匀,线性查找浪费时间;

2,不支持范围查询,避免不了全表扫描;

3,内存空间要求高。

MySQL中,InnoDB和MyISAM默认的索引是B+ Tree索引;Memory则同时支持Hash和Tree索引(可在创建时直接指定使用何种索引,具体移步)。

同时,Memory这种存储引擎“断电即毁”的特性也不再推荐使用。

B树和B+树之争

前置知识:知道mysql中索引即数据,数据即索引(页的存储结构);知道为何采用B树(多路平衡查找树),知道为何实际采用了B+树。

1,B+树空间利用率更高。B+树只在叶子节点存储实际数据,非叶子节点,B+树有了更多的空间存储索引,这样B+树越靠近矮胖,IO减少,

磁盘读写代价低,检索效率变高。

2,B+树查询效率更稳定。B+树的检索,任何检索路径都需要从根节点到叶子节点(只有叶子节点有数据),时间复杂度固定在O(LogN);

B树则在O(1)和O(LogN)之间。即二分查找。

3,B+树范围查询性能更优。 B+树的叶子节点使用了双向链表连接在一起,而且是严格的顺序存储,从左到右从小到大。

4,B+树由于叶子节点使用了链表进行串联,除了支持随机检索,还支持顺序检索。

一些常见概念

回表: 查询计划不是使用主键索引,即通过二级索引查找目标;而二级索引的B+树只存储了主键数据(索引列,主键),

如仍需要其它数据,需要再次根据主键去主键索引所在B+树查找一次数据的过程,即回表。

回表引发的问题:某些情况,使用了索引,但仍然触发了全表扫描(explain type='All')。因为此时查询优化器对比了回表IO次数和全表扫描的IO次数,选择了全表扫描。

MRR:MRR全称:Multi-Range Read Optimization(多范围读取优化),动机是减少随机磁盘访问的次数,实现对基表数据的更顺序扫描。

官网的解释在这。即把随机磁盘读转化为顺序磁盘读,提高查询性能(磁头运动&磁盘预读)。本质在做一件以空间换时间的事情。

下面这个图很形象借用一下:(红线表示查询路线,蓝线表示磁盘/磁头运动路线)

未开启MRR:

开启MRR:

上面的图来自文章MySQL的MRR到底是什么?

以空间换时间,这个空间指的是内存,内存大小设置在系统变量read_rnd_buffer_size,设置请参考官网

使用SQL命令:SELECT @@optimizer_switch

查看MRR是否已开启(默认开启)

索引覆盖:查询目标可直接从叶子节点获取数据,不需要回表,即为索引覆盖。

如下图:country_id是二级索引,查找目标刚好只查询主键索引和二级索引键值本身,直接使用二级索引的B+树就能查到。不需要回表,称为索引覆盖。

最左匹配原则(多列索引): 官网的解释在这里

举例:

有组合索引信息如下:

则验证的关键原则是:

-- 最左匹配原则要点:
-- 1,组合索引第一列(最左)作为第一个条件,只有接or不走索引,其它情况全部走索引;
-- 2,不以最左作为第一个条件,一般都不会走索引,唯有把组合索引条件都加上才会走(内部优化)。
explain select * from staff where first_name='Mike'; -- yes
explain select * from staff where last_name='Hillyer'; -- no
explain select * from staff where first_name='Mike' and last_name='Hillyer'; -- yes
explain select * from staff where last_name='Hillyer' and first_name='Mike'; -- yes(内部优化)
explain select * from staff where first_name='Mike' or last_name='Hillyer'; -- no
explain select * from staff where first_name='Mike' and(last_name='Hillyer' or last_name=''); -- yes

索引(条件)下推:即ICP,全称是Index Condition Pushdown Optimization,官网的解释在这里。我们一般叫索引下推,其实正式应该称为:索引条件下推。

怎么理解?下推什么呢? 顾名思义,Condition Pushdown,把查询条件往下推。官网的这句:

With ICP enabled, ... , the MySQL server pushes this part of the WHERE condition down to the storage engine.

翻译即是:ICP启用后,把where条件的部分从server层下推到storage engine层。

需要先了解MySQL的大概架构:

就是,原来where条件筛选在Server层这里,现在下推到存储引擎层去。

举例:

下表中,id是主键,name,age是联合索引。

查找姓张且年龄是10岁的记录:select * from tuser where name like '张%' and age=10;

没有使用ICP:二级索引找到主键1和4,分别回表去查找对应的完整记录,Server层再根据where条件的age=10进行筛选。这个过程要回表两次。

使用ICP:       二级索引找到主键1和4,存储引擎层(Server的下层)根据联合索引where条件age=10进行筛选。根据筛选结果再回表查到完整记录。这个过程回表1次。

上面的ICP举例和图片出自这里

使用执行计划分析时,使用索引下推在Extra栏位会出现:Using index condition信息,具体参见

MySQL默认启用索引(条件)下推。系统设置变量为:index_condition_pushdown

避免全表扫描:官网的解释在这里

使用查询计划分析时,对于大型表,应尽力避免type=All的情况。 表扫描非常昂贵。

本文阅读MySQL文档为5.7。

下一篇继续探索索引优化部分。

MySQL-带你上官网看索引的更多相关文章

  1. MySQL入门(参考官网)

    目录 一.登陆和退出 1. 远程主机 2. 登陆本机 3. 退出mysql 二.输入查询 三.创建和使用数据库 3.1 创建和选择数据库 3.2 创建表 3.3 将数据加载到表中 3.4 操作表格 3 ...

  2. jQuery layer弹出层插件 http://layer.layui.com/直接上官网学

    在许多网站中,经常用到弹出层,有时候为了达到更好的用户体验,你将写繁琐的css跟js,这款 jquery-layer可以让你想到即可做到的web弹窗/层js组件.layer侧重于用户灵活的自定义,为不 ...

  3. 不再用上官网,自己部署一套ElementUI官方最新文档

    ElementUI官方的访问速度一直很慢,公司内网也无法进行外网访问.故研究了下最新的ElementUI API(2.13.2)部署教程. 先上效果图 ElementUI文档部署过程 到github下 ...

  4. 跟着官网的例子学Reacjs (一)FilterableProductTable

    最近开始学习React,发现最好的方法不是看这个书那个书,而是直接上官网,一步步的跟着学习,真的获益匪浅.许多翻译的书上漏掉的知识点都可以学到. 入门的一些准备工作可以参照官网的步骤,引入依赖的核心包 ...

  5. Knockout.Js官网学习(简介)

    前言 最近一段时间在网上经常看到关于Knockout.js文章,于是自己就到官网看了下,不过是英文的,自己果断搞不来,借用google翻译了一下.然后刚刚发现在建立asp.net mvc4.0的应用程 ...

  6. 自建yum源解决Ceph搭建过程中从官网取包慢的问题

    最近项目组需要ceph环境,第一次搭建ceph,各种不顺,装了卸,卸了装,一遍又一遍地按照官网的操作进行.最气人的是网速差,从官网取包太慢.一轮尝试就浪费一上午. 因此想到本地新建yum源. 首先,按 ...

  7. Flume Sinks官网剖析(博主推荐)

    不多说,直接上干货! Flume Sources官网剖析(博主推荐) Flume Channels官网剖析(博主推荐) Flume Channel Selectors官网剖析(博主推荐) 一切来源于f ...

  8. 官网下载 Linux 上需要的 MySQL的步骤

    1.输入MySQL 官网地址  https://dev.mysql.com/  选择 download ->Community->MySQL Community Server 点击 MyS ...

  9. 1.JVM前奏篇(看官网怎么说)

    JVM(Java Virtual Machine) 前奏篇(看官网规范怎么说) 1.The relation of JDK/JRE/JVM 在下图中,我们所接触的,最熟悉,也是经常打交道的 最顶层 J ...

  10. Spring官网阅读(十一)ApplicationContext详细介绍(上)

    文章目录 ApplicationContext 1.ApplicationContext的继承关系 2.ApplicationContext的功能 Spring中的国际化(MessageSource) ...

随机推荐

  1. 12、jmeter逻辑控制器-临界区控制器

    临界区:说白了就是不并发了 一个个的像独木桥 使用场景:比如提交一个数据  需要一个一个的提交  一个个的改   在数据库改操作的时候 需要用到 临界区控制器 案例:临界区控制器

  2. jedis使用分布式锁

    import redis.clients.jedis.Jedis;public class A { public static void main(String[] args) throws Exce ...

  3. C/C++ 顺序表的初始化、添加、插入、删除(删除顺序表中指定的所有元素)

    #include <iostream> #include <stdlib.h> #define MAX_SIZE 100 using namespace std; typede ...

  4. 基于4g智能路由器的充电桩远程监测管理应用

    随着我国电动车保有量的持续增加,充电桩的需求也水涨船高,成为城市发展必备的基础设施之一.相较加油站,充电桩分布更广泛,部署场景更多样,与场景的融合程度也更深,诸如各类停车与充电二合一的站点.因此,对于 ...

  5. VSCODE C# 运行 找不到任务"BUILD"----C#常用命令

    使用 Visual Studio Code 创建 .NET 类库 - .NET | Microsoft Docs 安装vscode.vscode c#相关拓展.MINIGW64 1.创建文件夹 2.用 ...

  6. vue项目怎么链接开发服务器

    在前后端分离的前提下,完成前端的页面开发,就可以开始链接开发服务器 安装axios到项目中 npm install axios --save 安装完成后问你的后端开发人员要IP 后端会给一个IP以及端 ...

  7. ReentrantLock源码阅读

    默认构造方法初始化同步器为非公平同步器 /** * Creates an instance of {@code ReentrantLock}. * This is equivalent to usin ...

  8. AI 脸部美容,一键让你变瘦变美变老变年轻

    目录 项目效果 项目安装 安装环境 项目使用 项目效果 随着 AI 技术的发展,你不仅随时可以看到自己的老了之后的样子,还能看到自己童年的样子 随着这部分技术的开源,会有越来越多的应用,当然我觉得前景 ...

  9. java 中文繁简体转换工具 opencc4j 使用介绍 1.8.0

    Opencc4j Opencc4j 支持中文繁简体转换,考虑到词组级别. 在线体验 Features 特点 严格区分「一简对多繁」和「一简对多异」. 完全兼容异体字,可以实现动态替换. 严格审校一简对 ...

  10. 文心一言,通营销之学,成一家之言,百度人工智能AI大数据模型文心一言Python3.10接入

    "文心"取自<文心雕龙>一书的开篇,作者刘勰在书中引述了一个古代典故:春秋时期,鲁国有一位名叫孔文子的大夫,他在学问上非常有造诣,但是他的儿子却不学无术,孔文子非常痛心 ...