目录

  • 覆盖索引
    • 覆盖索引是什么
    • 如何实现覆盖索引
    • 无法实现使用覆盖索引的情况
    • 哪些场景适合使用覆盖索引来优化 `SQL`
      • 全表 `count` 查询优化
      • 列查询回表优化
      • 分页查询
    • 覆盖索引的情况下,为什么尽量不要使用 `select *`
  • 索引的使用原则
  • `sql` 的一些优化方法
  • 执行计划 `explain`
    • `explain` 各个字段的含义
      • `explain` 中的 `type` 字段
      • `explain` 中的 `Extra` 字段
  • 数据库大数据量查询的情况下,速度慢形成的原因

本文是 上一篇 mysql的索引 的续篇,接着我们的 Innodb 引擎的索引实现继续

覆盖索引

覆盖索引是什么

sql 语句的所求查询字段(select 列)和查询条件字段(where 子句)全都包含在一个索引中(联合索引),可以直接使用索引查询而不需要回表。这就是覆盖索引

select id,age from user where age = 10;
  • age 是普通索引,id 是主键索引
  • 查询的是 id,age,所以通过普通索引查询的第一步就能得到结果

如何实现覆盖索引

常见的方法是:将被查询的字段,建立到复合索引里去

select id,age from user where age = 10;

explain 分析:因为 age 是普通索引,使用到了 age 索引,通过一次扫描 B+ Tree 即可查询到相应的结果,这样就实现了覆盖索引

无法实现使用覆盖索引的情况

select id,age,name from user where age = 10;

explain 分析:age 是普通索引,但 name 列不在索引树上,所以通过 age 索引在查询到 idage 的值后,需要进行回表再查询 name 的值

为了实现索引覆盖,需要建复合索引 idx_age_name(age, name)

哪些场景适合使用覆盖索引来优化 SQL

全表 count 查询优化

mysql> create table user(-> id int(10) auto_increment,-> name varchar(30),-> age tinyint(4),-> primary key (id),-> )engine=innodb charset=utf8mb4;
select count(age) from user;

此时,是没有使用覆盖索引的。可以覆盖索引优化:创建 age 字段索引

create index idx_age on user(age);

列查询回表优化

前文在描述覆盖索引使用的例子就是

select id,age,name from user where age = 10;

使用覆盖索引:建复合索引 idx_age_name(age, name) 即可

分页查询

select id,age,name from user order by age limit 100,2;

因为 name 字段不是索引,所以在分页查询需要进行回表查询

使用索引覆盖:建组合索引 idx_age_name(age,name)

覆盖索引的情况下,为什么尽量不要使用 select *

知道了覆盖索引,就知道了为什么 sql 中要求尽量不要使用 select *,要写明具体要查询的字段。其中一个原因就是在使用到覆盖索引的情况下,不需要进入到数据区,数据就能直接返回,提升了查询效率

在用不到覆盖索引的情况下,也尽可能的不要使用 select *,如果行数据量特别多的情况下,可以减少数据的网络传输量。当然,这都视具体情况而定,通过 select 返回所有的字段,通用性会更强,一切有利必有弊

索引的使用原则

  • 表中的索引并不是越多越好,冗余或者无用索引会占用磁盘空间并且会影响增删改的效率
  • where 条件中,like 9%, like %9%,like%9,三种方式都用不到索引。后两种方式对于索引是无效的。第一种 9% 是不确定的,决定于列的离散型,结论上讲可以用到,如果发现离散情况特别差的情况下,查询优化器觉得走索引查询性能更差,还不如全表扫描
  • where 条件中 IN 可以使用索引;NOT IN 无法使用索引
  • 不要在使用索引的列上使用函数。否则,会导致索引失效
  • 索引列上不能有范围查询。否则,会导致索引失效
  • 不要在索引列上做任何计算(计算、函数、自动 or 手动类型转换),会导致索引失效
  • is not null 用不到索引,is null 可以用到索引
  • 复合索引中,需要遵循最佳左前缀法则
  • 复合索引中,精确匹配最左前列并范围匹配另一列,可以使用到索引
  • 复合索引中,如果查询有某个列的范围查询,其右边所有的列都无法使用索引

关于索引的使用原则详情:https://blog.csdn.net/weixin_44222272/article/details/106724773

sql 的一些优化方法

核心点是关注索引,防止索引失效,以便提高 sql 的查询效率。在索引未失效情况下,可以进一步考虑使用覆盖索引查询

  • 对查询进行优化,要尽量避免全表扫描。首先应考虑在 whereorder by 涉及的列上建立索引
  • 应尽量避免在 where 子句中对字段进行 null 值的判断,否则将导致引擎放弃使用索引而进行全表扫描
  • 应尽量避免在 where 子句中使用 !=,<,> 操作符。否则将导致引擎放弃使用索引而进行全表扫描
  • 尽量避免在 where 子句中使用 or 来连接条件。如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描
  • 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
  • 注意where 条件中 IN 可以使用索引;NOT IN 无法使用索引
  • 在查询时,注意 inexists 的使用。如果查询的两个表数据量大小相当,那么用 inexists 差别不大,如果一个表数据量较小一个表数据量较大,则子查询中表数据量大的用 exists,子查询中表数据量小的用 in
  • 在查询时,应尽量使用覆盖索引进行优化 sql

执行计划 explain

我们常常用到 explain 这个命令来查看一个这些 SQL语句的执行计划,查看该 SQL 语句有没有使用上了索引,有没有做全表扫描,这都可以通过 explain 命令来查看

EXPALIN 只能解释 SELECT 操作

explain select * from user;

explain 各个字段的含义

  • id : 表示 SQL 执行的顺序的标识, SQL 从大到小的执行
  • select_type:表示查询中每个 select 子句的类型
  • table:显示这一行的数据是关于哪张表的,有时不是真实的表名字
  • type:表示 mysql 在表中找到所需行的方式,又称访问类型。常用的类型有:ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)
  • possible_keys:指出 mysql 能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
  • Keykey 列显示 mysql 实际决定使用的键(索引),如果没有选择索引,键是NULL
  • key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len 显示的值为索引字段的最大可能长度,并非实际使用长度,即 key_len 是根据表定义计算而得,不是通过表内检索出的)
  • ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
  • rows:表示 mysql 根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数,理论上行数越少,查询性能越好
  • Extra:该列包含 mysql 解决查询的详细信息

explain 中的 type 字段

一般来说,得保证查询至少达到 range 级别,最好能达到 ref

  • eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配
  • ref:非唯一性索引扫描,返回匹配某个单独值的所有行
  • range:只检索给定范围的行,使用一个索引来选择行
  • ALL:遍历全表获得匹配的行
  • indexindexALL 的区别为 index 类型只遍历索引树,这通常比 ALL 快,因为索引文件通常比数据文件小

explain 中的 Extra 字段

  • Using filesort:说明 mysql 对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取
  • Using temporary:使用了临时表保存中间结果,mysql 在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by
  • using index condition:会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行
  • Using index:表示使用了覆盖索引,避免访问了表的数据行,效率不错
  • using where: 未使用索引,通过 where 条件过滤

数据库大数据量查询的情况下,速度慢形成的原因

  • 没有索引或者没有用到索引(这是查询慢最常见的问题)
  • 查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)
  • 数据库存在锁或者发生死锁(这也是查询慢最常见的问题)
  • 返回了不必要的行和列
  • 查询语句写的不好,没有很好的优化

mysql的索引(二)相关推荐

  1. MySQL的索引(二十三)

    勿以恶小而为之,勿以善小而不为--------------------------刘备 上一章简单介绍了 MySQL的视图(二十二),如果没有看过,请观看上一章 一. 索引 一.一 索引的产生 前面已 ...

  2. mysql 唯一索引 二叉法_mysql 唯一索引

    1.一个列的唯一索引 mysql> create database pay; Query OK, 1 row affected (0.03 sec) mysql> use pay; Dat ...

  3. mysql覆盖索引二次查找_mysql中关于覆盖索引的知识点总结

    如果一个索引包含(或覆盖)所有需要查询的字段的值,称为'覆盖索引'. 覆盖索引是一种非常强大的工具,能大大提高查询性能,只需要读取索引而不需要读取数据,有以下优点: 1.索引项通常比记录要小,所以My ...

  4. MySQL优化(二):索引的类型、匹配原则、创建原则

    目录 索引的优缺点 索引类型 聚簇索引(主键索引) 非聚簇索引(二级索引.辅助索引) 索引匹配的原则 最左匹配原则 无法使用索引的场景 索引创建的原则 使不使用索引的依据到底是什么? 参考 索引的优缺 ...

  5. mysql 索引 二_MySQL之索引(二)

    高性能的索引策略 正确地创建和使用索引是实现高性能查询的基础.在MySQL之索引(一)这一章中我们介绍了各种类型的索引及其对应的优缺点.现在我们一起来看看如何真正地发挥这些索引的优势. 独立的列 我们 ...

  6. 为了把mysql的索引底层原理讲清楚,我把计算机翻了个底朝天

    来自:非科班的科班 什么是索引 概念:索引是提高mysql查询效率的数据结构.总的一句话概括就是索引是一种数据结构. 数据库查询是数据库的最主要功能之一.设计者们都希望查询数据的速度能尽可能的快,因此 ...

  7. mysql单列索引和多列索引_浅谈MySQL索引优化

    索引基础知识总结及常见索引优化手段 一.索引简介 什么是索引? MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 可以简单理解为"排好序的快速查找数据 ...

  8. mysql+零时数据结构,MySql主要索引数据结构

    索引数据结构 1. 二叉搜索树(Binary Search Tree) 二叉搜索树是每个节点最多有两个子节点的树,按照右侧子节点大于本节点,左侧子节点小于本节点的规律排列,可以用作搜索,结构如下图所示 ...

  9. mysql联合索引的数据结构

    一.本文主要讲解的内容有: 联合索引在B+树上的存储结构 联合索引的查找方式 为什么会有最左前缀匹配原则 在分享这篇文章之前,我在网上查了关于MySQL联合索引在B+树上的存储结构这个问题,翻阅了很多 ...

  10. mysql 强制索引循序_mysql 强制走索引

    查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端.虽然过程 ...

最新文章

  1. 数据挖掘(10):卷积神经网络算法的一个实现
  2. Python爬虫学习获取腾讯新闻并存入Csv文件
  3. 自行车也能做智能升级?AliOS以想象力为智慧出行带来新体验
  4. mvn clean install时出现 java.lang.ClassCastException
  5. Scrum:The Definition of Done —— 作业有没有写完呢?
  6. 把ipad变成电脑的音箱
  7. 卫星定位领域相关基础知识汇总
  8. WinRAR下载官方免费版
  9. SpringBoot整合thymeleaf和Shiro项目绑定JS接口安全域名问题
  10. 2020NISP一级(模拟题一)
  11. 【老卫搞机】136期:华为开发者联盟社区2022年度战码先锋2期开源贡献之星
  12. 二建代报名 2022年二级建造师什么时候报名
  13. Hibiscus的脑机接口学习周报(2023/1/23~2023/1/29)
  14. IE8-下背景色半透明滤镜在jquery动画中失效问题记录
  15. HDU - 1173 采矿
  16. 第十章 DCEP简介
  17. 一 贷款基础指标介绍
  18. java .gml格式_GML格式错误
  19. 昨天,我终于见到了传说中的牛叉架构老炮儿...
  20. linux基本命令(3)——pwd命令

热门文章

  1. 极客大学架构师训练营 系统安全架构 系统稳定高可用 PBKDF2加密算法 第11次作业
  2. 计算机控制技术数据存储器有,计算机控制技术复习资料.doc
  3. c语言显示cpuid_ccpuid:CPUID信息模块。范例:显示所有的CPUID信息
  4. 查看docker镜像内部端口号_Docker 安装部署
  5. 2021-09-09316. 去除重复字母 栈
  6. not是什么意思在c语言,为什么在C样式语言中逻辑NOT运算符是“!”而不是“ ~~”?...
  7. 现代通信原理4.2:随机过程
  8. 【2016-2017 ACM-ICPC (ECNA 2016) F】Removal Game【区间DP】
  9. admin登录 404_Shiro Springboot 集群共享Session (Redis)+单用户登录
  10. linux 输入法框架xim,基于XIM协议的输入法原理与实现