本期来谈谈覆盖索引与延迟关联。在此之前,我们先简单建立一个订单表 Orders 用于举例说明。表中共包含 3 个字段:

id

int

product_id

name

CREATE

TABLE

`orders`

`id`

int

10

NOT

NULL

COMMENT

'订单 ID'

`product_id`

int

10

DEFAULT

NULL

COMMENT

'商品 ID'

`name`

varchar

255

CHARACTER

SET

COLLATE

DEFAULT

NULL

COMMENT

'订单名称'

KEY

`id`

KEY

`product_idx`

`product_id`

USING

ENGINE

InnoDB

DEFAULT

CHARSET

COLLATE

覆盖索引

什么是覆盖索引?

根据索引

不包含

覆盖索引

MyISAM

product_id

SELECT product_id FROM orders

EXPLAIN

SELECT

FROM

----+-------------+--------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+

----+-------------+--------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+

----+-------------+--------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+

set

0.00

id

SELECT id, product_id FROM orders WHERE product_id = 1

product_id

product_id = 1

通过该子结点指针读取磁盘上的数据行

id

由于 MyISAM 的叶子结点存储着指向数据行的指针,该查询多了一步回表操作,无法使用覆盖索引。

EXPLAIN

SELECT

id

FROM

WHERE

1

----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------+

----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------+

----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------+

set

0.00

MyISAM 索引结构

InnoDB

二级索引的叶子结点保存着行的主键值

InnoDB 二级索引的叶子结点包含行主键值

SELECT id, product_id FROM orders WHERE product_id = 1

EXPLAIN

SELECT

id

FROM

WHERE

1

----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+

----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+

----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+

set

0.01

Extra

Using index

product_id

product_id = 1

id

查询轨迹并未进行回表取值。

延迟关联

deferred join

在查询的第一阶段 MySQL 使用覆盖索引,再通过该覆盖索引查询到的结果到外层查询匹配需要的所有列值。

这样说有些抽象,我们来看看下面的例子。

用延迟关联优化分页(LIMIT)

LIMIT

LIMIT 10000, 20

EXPLAIN

SELECT

FROM

LIMIT

10000

20

----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+

----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+

----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+

尽可能使用索引覆盖扫描,而不是查询所有列

EXPLAIN

SELECT

FROM

AS

JOIN

SELECT

id

FROM

LIMIT

10000

20

AS

ON

----+-------------+------------+------------+-------+---------------+-------------+---------+------------+------+----------+-------------+

----+-------------+------------+------------+-------+---------------+-------------+---------+------------+------+----------+-------------+

----+-------------+------------+------------+-------+---------------+-------------+---------+------------+------+----------+-------------+

这样一来,MySQL 在 SQL 语句的「内层」进行扫描时使用了覆盖索引,「外层」再通过索引树找到相关的数据行,直接减少了扫描的数据量。

总结

只需扫描索引,无须回表

deferred join

参考资料

《高性能 MySQL》

[1]

参考资料

[1]

https://book.douban.com/subject/23008813/

更多阅读

5分钟掌握在 Cython 中使用 C++

5 分钟掌握 Python 中常见的配置文件

5 分钟掌握 Python 中的 Hook 钩子函数

点击下方阅读原文加入

社区会员

mysql延迟关联为什么快_MySQL 覆盖索引与延迟关联详解相关推荐

  1. mysql innodb 索引 延迟更新_Mysql覆盖索引与延迟关联

    延迟关联:通过使用覆盖索引查询返回需要的主键,再根据主键关联原表获得需要的数据. 为什innodb的索引叶子节点存的是主键,而不是像myisam一样存数据的物理地址指针? 如果存的是物理地址指针不就不 ...

  2. mysql中的执行计划_MySQL中的执行计划explain详解

    一.用法及定义: explain为sql的执行计划.在sql前面加上explain关键字即可 如:explain select * from tbl_emp; 名词解释: id:[操作表的顺序] 1. ...

  3. mysql默认使用悲观锁_mysql乐观锁和悲观锁详解

    mysql乐观锁和悲观锁详解 相信很多朋友在面试的时候,都会被问到乐观锁和悲观锁的问题,如果不清楚其概念和用法的情况下,相信很多朋友都会感觉很懵逼,那么面试的结果也就不言而喻了. 那么乐观锁和悲观锁到 ...

  4. mysql语句中事务可靠性_MySql的事务使用与示例详解

    在MySQL中,事务就是一个逻辑工作单元的一系列步骤.事务是用来保证数据操作的安全性. 事务的特征: 1.Atomicity(原子性) 2.Consistency(稳定性,一致性) 3.Isolati ...

  5. mysql命令导入导出数据库_MYSQL命令行导入导出数据库详解

    Mysql命令行导入数据库: 1,将要导入的.sql文件移至bin文件下,这样的路径比较方便 2,同上面导出的第1步 3,进入MySQL:mysql -u 用户名 -p 如我输入的命令行:mysql ...

  6. mysql修改表结构例子_mysql修改表结构方法实例详解

    本文实例讲述了mysql修改表结构方法.分享给大家供大家参考.具体如下: mysql修改表结构使用ALTER TABLE语句,下面就为您详细介绍mysql修改表结构的语句写法,希望对您学习mysql修 ...

  7. mysql表分区数量限制_MySQL分区表的局限和限制详解

    禁止构建 分区表达式不支持以下几种构建: 存储过程,存储函数,UDFS或者插件 声明变量或者用户变量 可以参考分区不支持的SQL函数 算术和逻辑运算符 分区表达式支持+,-,*算术运算,但是不支持DI ...

  8. mysql基于时间盲注_MYSQL基于时间的盲注详解

    MYSQL基于时间的盲注 联合查询,报错注入,以及布尔盲注,都是基于攻击网站会回显消息,或者将错误信息返回在前端,或者会返回web页面的正确或错误 但是有时候网站关闭了错误回显或过滤了某些关键字,网页 ...

  9. mysql的double类型数据_mysql数据类型double和decimal区别详解

    实数是带有小数部分的数字.然而,它们不只是为了存储小数部分,也可以使用 DEClMAL 存储比 BIGINT还大的整数. MySQL 既支持精确类型,也支持不精确类型. FLOAT 和  DOUBLE ...

最新文章

  1. 【每日一算法】实现strStr()
  2. 【错误记录】Android Studio 中查看 Gradle 配置的方法源码 ( 配置 gradle-wrapper.properties 中版本为 gradle-x.x.x-all.zip )
  3. 博为峰JavaEE技术文章 —— Hibernate域模型(2)
  4. 2018年1月 常用的linux命令
  5. PHP中mysql如何添加记录_PHP向MySql提交数据添加记录的简单代码_PHP教程
  6. C++函数分文件编写
  7. 华晨中华v3车质量怎么样_宝马发动机加持,销量仅个位数?这些车有点惨
  8. dede使用方法---用js让当前导航高亮显示
  9. 基于matlab的语音识别系统
  10. java 创建txt_JAVA读取TXT文件、新建TXT文件、写入TXT文件
  11. 爬取msdn.itellyou.cn网站
  12. APICloud介绍
  13. 医学院校教师备课系统的信息安全性研究
  14. svc预测概率_机器学习朴素贝叶斯 SVC对新闻文本进行分类
  15. 如何使用JAVA代码生成一个简单的二维码
  16. 知乎神回复:曾经删了雷军代码的人现在怎么样了?
  17. 计算机信息安全技术学习资料汇总
  18. 如何辨别真假IPHONE4 , IPHONE 4S ?
  19. 量化投资中常遇到的两个问题
  20. iOS开发系列--网络开发

热门文章

  1. 《Linux多线程服务端编程——使用muduo C++网络库》读书笔记
  2. halcon select_shape_xld按区域大小描绘xld
  3. char data[0]用法总结
  4. C++多线程实例(_beginThreadex创建多线程)
  5. Veebot-自动静脉抽血机器人
  6. 【数据库学习笔记】——创建数据库文件
  7. 机器学习之支持向量机SVM之python实现ROC曲线绘制(二分类和多分类)
  8. 现代制造工程02:第一部分——刀具(含2个易考点)
  9. c++突破网关屏蔽_为什么加了屏蔽罩,测试效果反而不好?
  10. java tempfile read_Java 文件操作