mysql的索引(二)
目录
- 覆盖索引
- 覆盖索引是什么
- 如何实现覆盖索引
- 无法实现使用覆盖索引的情况
- 哪些场景适合使用覆盖索引来优化 `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
索引在查询到 id
和 age
的值后,需要进行回表再查询 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
的查询效率。在索引未失效情况下,可以进一步考虑使用覆盖索引查询
- 对查询进行优化,要尽量避免全表扫描。首先应考虑在
where
和order by
涉及的列上建立索引 - 应尽量避免在
where
子句中对字段进行null
值的判断,否则将导致引擎放弃使用索引而进行全表扫描 - 应尽量避免在
where
子句中使用!=,<,>
操作符。否则将导致引擎放弃使用索引而进行全表扫描 - 尽量避免在
where
子句中使用or
来连接条件。如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描 - 应尽量避免在
where
子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描 - 注意
where
条件中IN
可以使用索引;NOT IN
无法使用索引 - 在查询时,注意
in
和exists
的使用。如果查询的两个表数据量大小相当,那么用in
和exists
差别不大,如果一个表数据量较小一个表数据量较大,则子查询中表数据量大的用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
能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用Key
:key
列显示mysql
实际决定使用的键(索引),如果没有选择索引,键是NULL
key_len
:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len
显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len
是根据表定义计算而得,不是通过表内检索出的)ref
:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值rows
:表示mysql
根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数,理论上行数越少,查询性能越好Extra
:该列包含mysql
解决查询的详细信息
explain
中的 type
字段
一般来说,得保证查询至少达到 range
级别,最好能达到 ref
eq_ref
:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配ref
:非唯一性索引扫描,返回匹配某个单独值的所有行range
:只检索给定范围的行,使用一个索引来选择行ALL
:遍历全表获得匹配的行index
:index
与ALL
的区别为index
类型只遍历索引树,这通常比ALL
快,因为索引文件通常比数据文件小
explain
中的 Extra
字段
Using filesort
:说明mysql
对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取Using temporary
:使用了临时表保存中间结果,mysql
在对查询结果排序时使用临时表。常见于排序order by
和分组查询group by
using index condition
:会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用WHERE
子句中的其他条件去过滤这些数据行Using index
:表示使用了覆盖索引,避免访问了表的数据行,效率不错using where
: 未使用索引,通过where
条件过滤
数据库大数据量查询的情况下,速度慢形成的原因
- 没有索引或者没有用到索引(这是查询慢最常见的问题)
- 查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)
- 数据库存在锁或者发生死锁(这也是查询慢最常见的问题)
- 返回了不必要的行和列
- 查询语句写的不好,没有很好的优化
mysql的索引(二)相关推荐
- MySQL的索引(二十三)
勿以恶小而为之,勿以善小而不为--------------------------刘备 上一章简单介绍了 MySQL的视图(二十二),如果没有看过,请观看上一章 一. 索引 一.一 索引的产生 前面已 ...
- mysql 唯一索引 二叉法_mysql 唯一索引
1.一个列的唯一索引 mysql> create database pay; Query OK, 1 row affected (0.03 sec) mysql> use pay; Dat ...
- mysql覆盖索引二次查找_mysql中关于覆盖索引的知识点总结
如果一个索引包含(或覆盖)所有需要查询的字段的值,称为'覆盖索引'. 覆盖索引是一种非常强大的工具,能大大提高查询性能,只需要读取索引而不需要读取数据,有以下优点: 1.索引项通常比记录要小,所以My ...
- MySQL优化(二):索引的类型、匹配原则、创建原则
目录 索引的优缺点 索引类型 聚簇索引(主键索引) 非聚簇索引(二级索引.辅助索引) 索引匹配的原则 最左匹配原则 无法使用索引的场景 索引创建的原则 使不使用索引的依据到底是什么? 参考 索引的优缺 ...
- mysql 索引 二_MySQL之索引(二)
高性能的索引策略 正确地创建和使用索引是实现高性能查询的基础.在MySQL之索引(一)这一章中我们介绍了各种类型的索引及其对应的优缺点.现在我们一起来看看如何真正地发挥这些索引的优势. 独立的列 我们 ...
- 为了把mysql的索引底层原理讲清楚,我把计算机翻了个底朝天
来自:非科班的科班 什么是索引 概念:索引是提高mysql查询效率的数据结构.总的一句话概括就是索引是一种数据结构. 数据库查询是数据库的最主要功能之一.设计者们都希望查询数据的速度能尽可能的快,因此 ...
- mysql单列索引和多列索引_浅谈MySQL索引优化
索引基础知识总结及常见索引优化手段 一.索引简介 什么是索引? MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 可以简单理解为"排好序的快速查找数据 ...
- mysql+零时数据结构,MySql主要索引数据结构
索引数据结构 1. 二叉搜索树(Binary Search Tree) 二叉搜索树是每个节点最多有两个子节点的树,按照右侧子节点大于本节点,左侧子节点小于本节点的规律排列,可以用作搜索,结构如下图所示 ...
- mysql联合索引的数据结构
一.本文主要讲解的内容有: 联合索引在B+树上的存储结构 联合索引的查找方式 为什么会有最左前缀匹配原则 在分享这篇文章之前,我在网上查了关于MySQL联合索引在B+树上的存储结构这个问题,翻阅了很多 ...
- mysql 强制索引循序_mysql 强制走索引
查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端.虽然过程 ...
最新文章
- 数据挖掘(10):卷积神经网络算法的一个实现
- Python爬虫学习获取腾讯新闻并存入Csv文件
- 自行车也能做智能升级?AliOS以想象力为智慧出行带来新体验
- mvn clean install时出现 java.lang.ClassCastException
- Scrum:The Definition of Done —— 作业有没有写完呢?
- 把ipad变成电脑的音箱
- 卫星定位领域相关基础知识汇总
- WinRAR下载官方免费版
- SpringBoot整合thymeleaf和Shiro项目绑定JS接口安全域名问题
- 2020NISP一级(模拟题一)
- 【老卫搞机】136期:华为开发者联盟社区2022年度战码先锋2期开源贡献之星
- 二建代报名 2022年二级建造师什么时候报名
- Hibiscus的脑机接口学习周报(2023/1/23~2023/1/29)
- IE8-下背景色半透明滤镜在jquery动画中失效问题记录
- HDU - 1173 采矿
- 第十章 DCEP简介
- 一 贷款基础指标介绍
- java .gml格式_GML格式错误
- 昨天,我终于见到了传说中的牛叉架构老炮儿...
- linux基本命令(3)——pwd命令
热门文章
- 极客大学架构师训练营 系统安全架构 系统稳定高可用 PBKDF2加密算法 第11次作业
- 计算机控制技术数据存储器有,计算机控制技术复习资料.doc
- c语言显示cpuid_ccpuid:CPUID信息模块。范例:显示所有的CPUID信息
- 查看docker镜像内部端口号_Docker 安装部署
- 2021-09-09316. 去除重复字母 栈
- not是什么意思在c语言,为什么在C样式语言中逻辑NOT运算符是“!”而不是“ ~~”?...
- 现代通信原理4.2:随机过程
- 【2016-2017 ACM-ICPC (ECNA 2016) F】Removal Game【区间DP】
- admin登录 404_Shiro Springboot 集群共享Session (Redis)+单用户登录
- linux 输入法框架xim,基于XIM协议的输入法原理与实现