explain是mysql的关键字吗_mysql 中的explain关键字
mysql优化在实际的开发中是很重要,有很多可以评估自己写的sql的质量与效率,mysql为我们提供了一个辅助武器explain,它向我们展示了mysql接收到一条sql语句的执行计划,根绝explain返回的结果可以知道sql写的怎样,
demo数据库
建表语句
CREATE TABLE test (
id INT(11) NOT NULL AUTO_INCREMENT,
uname VARCHAR(255),
age int,
PRIMARY KEY (id)
);
alter table test add index uname_index(uname);
复制代码
表中数据如下
id
uname
age
1
lxh
24
3
zhangsan
23
10
sdsx
12
11
x33
35
explain的关键字有很多,此处只讲解最关键的type,key,rows
type
类型,官方全程“join type”,意思是“连接类型”,注意这里不是字面意思量表之间的链接,确切说是数据库引擎查找表的一种方式,在《高性能mysql》一书中作者更是觉得称呼它为访问类型更贴切一些;
type的类型达到了14种之多,这里只记录和理解最重要且经常遇见的六种类型,它们分别是all,index,range,ref,eq_ref,const。从左到右,它们的效率依次是增强的
all
全表扫描,如果只是查找一个数据项的sql出现了all类型,代表sql处于一种最原声的状态,有很大的优化空间,就好比一万个人中找一个人,只能挨个找一遍
以test表为例
index
另一种方式的全表扫描,只不过是按照索引的顺序,
ref
查找条件列使用了索引而且不为主键和unique,意思就是虽然使用了索引,但该索引列的值并不唯一,有重复
比如,test表的索引是 uname
eq_ref
ref_eq 与 ref相比牛的地方是,它知道这种类型的查找结果集只有一个,使用了主键或者唯一性索引进行查找时,
下面这两张表一张学生表,一张成绩表,成绩表里的学生id,t_id,就是使用了主键
-- 建表语句
create table ref_stu2 (
id INT(11) NOT NULL AUTO_INCREMENT,
uname VARCHAR(255),
age VARCHAR(255),
PRIMARY KEY (id)
);
create table ref_score2 (
id INT(11) NOT NULL AUTO_INCREMENT,
stu_id int(11) not null,
score int(11),
PRIMARY KEY (id)
);
explain select * from ref_stu2 stu, ref_score2 sc where stu.id = sc.stu_id;
复制代码
输出结果
id
select_type
table
partitions
type
possible_keys
key
key_len
ref
rows
filtered
Extra
1
SIMPLE
stu
NULL
ALL
PRIMARY
NULL
NULL
NULL
1
100
NULL
1
SIMPLE
sc
NULL
eq_ref
uk_score_stuid
uk_score_stuid
4
1
100
NULL
const
将一个主键放置到where后面作为条件查询,mysql优化器就能把这次查询优化转化为一个常量
explain select * from ref_stu2 stu where stu.id = 1;
复制代码
执行结果如下
id
select_type
table
partitions
type
possible_keys
key
key_len
ref
rows
filtered
Extra
1
SIMPLE
stu
null
const
PRIMARY
PRIMARY
4
const
1
100
null
key
查询使用到的索引,type类型为index_merge(查询使用了两个以上的索引)时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。
rows
这里是执行计划中估算的扫描行数,不是精确值,值越小,代表效率越高
索引覆盖
覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取
关于like关键字是否用到索引
总结:like关键字是否使用索引的前提是做前缀原则,即‘x’和‘x%’是使用索引的,他们的执行计划中type都是range,rows都是比表的行数少的,而其他两个type都是index,这种情况叫,全索引扫描,具体介绍如下,
如果模糊查询时,查询是否包含某个字符串,可以采用locate函数,select * from test where locate("x",uname);查询test表中uname字段,含有字符串‘x’的数据。
mysql 全表扫描、全索引扫描、索引覆盖(覆盖索引)
full index scan:全索引扫描,查询时,遍历索引树来获取数据行。如果数据不是密集的会产生随机IO
在执行计划中是Type列,index
full table scan:通过读物理表获取数据,顺序读磁盘上的文件。这种情况会顺序读磁盘上的文件。
在执行计划中是Type列,all
covering index:覆盖索引,如果where条件的列和返回的数据在一个索引中,那么不需要回查表,那么就叫覆盖索引。
在执行计划中是extra那一列,using index
full index scan vs full table scan
全索引扫描一般情况下比全表扫描好,但一定不是绝对的
大多数数据是存在磁盘上的,读取磁盘的次数是影响效率的关键。
由于索引扫描后要利用索引中的指针去逐一访问记录,假设每个记录都使用索引访问,则读取磁盘的次数是查询包含的记录数T;
如果表扫描则读取磁盘的次数是存储记录的块数B;
如果T>B 的话索引就没有优势了,对于大多数数据库来说,这个比例是10%(oracle,postgresql等),最终执行的时候,先对结果数量估算,如果小于(T
引用网上的一个例子
已知如下信息:
假设一张表含有10万行数据--------100000行
我们要读取其中20%(2万)行数据----20000行
表中每行数据大小80字节----------80bytes
数据库中的数据块大小8K----------8000bytes
所以有以下结果:
每个数据块包含100行数据---------100行(数据块大小/每行数据的大小 8000/80 )
这张表一共有1000个数据块--------1000块(数据总条数/每个块包含的数据个数 100000/100)
背后的故事:
通过索引读取20000行数据 = 约20000个table access by rowid = 需要处理20000个块来执行这个查询(通过索引去读数据,在索引中找到一个键值,然后这个键值对应的rowid去读表数据,rowid只对应一条记录,所以读一个块也只是为了找到对应rowid的那条记录,所以一次在一个块中只读一条记录)
而如果是全表扫描呢,这个表一共是1000块,也就1000次读取,采用后者明显效率高。
小计:最近在看mongo,发现原来mongo里也有这个关键字,哈哈,看来是通用的啊
安利一个我的博客:Linnxh的博客
explain是mysql的关键字吗_mysql 中的explain关键字相关推荐
- mysql获取当月最后一天_mysql中获取本月第一天、本月最后一天、上月第一天、上月最后一天
mysql获取当月最后一天_mysql中获取本月第一天.本月最后一天.上月第一天.上月最后一天等等 转自: https://blog.csdn.net/min996358312/article/det ...
- mysql添加临时索引_mysql 中添加索引的三种方法
在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以通过不同的应用场景来进行索引的新建,在此列出三种新建索引的方法 mysql 中添加索引的三种方法 1.1 新建表中添加索 ...
- mysql 中有没有临时表_MySQL 中的两种临时表
来源:阿里云RDS - 数据库内核组 链接:http://mysql.taobao.org/monthly/2016/06/07/ 外部临时表 通过CREATE TEMPORARY TABLE 创建的 ...
- mysql 触发器 库存管理_Mysql中的触发器(库存、用户订单中用到)
什么是触发器? 触发器是数据库的一个程序,他是用来监听着数据表的某个行为,一旦数据表的这个行为发生了,马上执行相应的sql语句 触发器的语法结构: create trigger触发器的名称触发器事件o ...
- mysql 主外键_mysql中主外键关系
一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, ...
- mysql日期格式化季度_mysql中常用日期比较与计算函数
MySql中时间比较的实现 unix_timestamp() unix_timestamp 函数可以接受一个参数,也可以不使用参数. 它的返回值是一个无符号的整数.不使用参数,它返回自1970年1月1 ...
- mysql 生明变量_mysql中变量的使用
4.4.1 局部变量 局部变量是用户可自定义的变量,它的作用范围仅在程序内部.在程序中通常用来储存从表中查询到的数据,或当作程序执行过程中暂存变量使用.局部变量必须以"@"开头,而 ...
- mysql if exists用法_MySQL中EXISTS的用法
比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(SELECT OrderID F ...
- mysql sql 时间比较_mysql中sql语句进行日期比较
这里是一个使用日期函数的例子.下面的查询选择了所有记录,其date_col的值是在最后30天以内: mysql> SELECT something FROM table WHERE TO_DAY ...
- mysql查看执行计划_MySql中如何使用 explain 查询 SQL 的执行计划
explain命令是查看查询优化器如何决定执行查询的主要方法. 这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的. 1.什么是MyS ...
最新文章
- 关于年长程序员的5个误传
- XLSReadWriteII5使用参考
- python错误-Python错误解决
- 使用java.util.zip对字符串进行压缩和解压缩
- 使用 TensorFlow 的公司
- No result defined for action action.QueryAction and result result
- 无代码iVX编程实现简单魂斗罗
- eos和以太坊有什么关系_【EOS价格分析】EOS,宇宙,以太坊价格分析:8月6日
- c基础学汇编语言,王爽《汇编语言》学习笔记、习题(第一章 基础知识)
- 09-Elasticsearch重要的系统配置
- 当Shell遇上了NodeJS
- leetcode之移除链表的元素
- Linux必备命令 - 常用命令集
- 动易sitefactory 3.0 模板标签系统
- 移动硬盘格式化了?这样恢复数据
- 品味之旅见行见心 ——香港科大EMBA郎酒庄园深度体验之旅
- 右手定则判断向量积的方向
- Python开发-面向对象编程-王大鹏-专题视频课程
- iphone铃声制作
- 天池比赛首次参加记录
热门文章
- 用c语言编程一个英尺转换器,PTA-基础编程题目厘米换算英尺英寸-C基础版
- va_list(可变参数函数的使用)
- ResNet论文翻译——中文版
- Python中pass是什么?
- 小米平板2刷哪个系统更流畅_Windows 10版小米平板2简测:流畅度不及自家MIUI版...
- [RK3288][Android7.1]调试笔记 --- Settings设置WLAN热点支持遥控器弹出软键盘输入法
- 全球研究:持续绩效管理可提高竞争优势
- A Visual, Intuitive Guide to Imaginary Numbers
- U盘安装Windows 11正式版绕过TPM检查
- attribute和property的区别 (转载)