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关键字相关推荐

  1. mysql获取当月最后一天_mysql中获取本月第一天、本月最后一天、上月第一天、上月最后一天

    mysql获取当月最后一天_mysql中获取本月第一天.本月最后一天.上月第一天.上月最后一天等等 转自: https://blog.csdn.net/min996358312/article/det ...

  2. mysql添加临时索引_mysql 中添加索引的三种方法

    在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以通过不同的应用场景来进行索引的新建,在此列出三种新建索引的方法 mysql 中添加索引的三种方法 1.1 新建表中添加索 ...

  3. mysql 中有没有临时表_MySQL 中的两种临时表

    来源:阿里云RDS - 数据库内核组 链接:http://mysql.taobao.org/monthly/2016/06/07/ 外部临时表 通过CREATE TEMPORARY TABLE 创建的 ...

  4. mysql 触发器 库存管理_Mysql中的触发器(库存、用户订单中用到)

    什么是触发器? 触发器是数据库的一个程序,他是用来监听着数据表的某个行为,一旦数据表的这个行为发生了,马上执行相应的sql语句 触发器的语法结构: create trigger触发器的名称触发器事件o ...

  5. mysql 主外键_mysql中主外键关系

    一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, ...

  6. mysql日期格式化季度_mysql中常用日期比较与计算函数

    MySql中时间比较的实现 unix_timestamp() unix_timestamp 函数可以接受一个参数,也可以不使用参数. 它的返回值是一个无符号的整数.不使用参数,它返回自1970年1月1 ...

  7. mysql 生明变量_mysql中变量的使用

    4.4.1 局部变量 局部变量是用户可自定义的变量,它的作用范围仅在程序内部.在程序中通常用来储存从表中查询到的数据,或当作程序执行过程中暂存变量使用.局部变量必须以"@"开头,而 ...

  8. mysql if exists用法_MySQL中EXISTS的用法

    比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(SELECT OrderID F ...

  9. mysql sql 时间比较_mysql中sql语句进行日期比较

    这里是一个使用日期函数的例子.下面的查询选择了所有记录,其date_col的值是在最后30天以内: mysql> SELECT something FROM table WHERE TO_DAY ...

  10. mysql查看执行计划_MySql中如何使用 explain 查询 SQL 的执行计划

    explain命令是查看查询优化器如何决定执行查询的主要方法. 这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的. 1.什么是MyS ...

最新文章

  1. 关于年长程序员的5个误传
  2. XLSReadWriteII5使用参考
  3. python错误-Python错误解决
  4. 使用java.util.zip对字符串进行压缩和解压缩
  5. 使用 TensorFlow 的公司
  6. No result defined for action action.QueryAction and result result
  7. 无代码iVX编程实现简单魂斗罗
  8. eos和以太坊有什么关系_【EOS价格分析】EOS,宇宙,以太坊价格分析:8月6日
  9. c基础学汇编语言,王爽《汇编语言》学习笔记、习题(第一章 基础知识)
  10. 09-Elasticsearch重要的系统配置
  11. 当Shell遇上了NodeJS
  12. leetcode之移除链表的元素
  13. Linux必备命令 - 常用命令集
  14. 动易sitefactory 3.0 模板标签系统
  15. 移动硬盘格式化了?这样恢复数据
  16. 品味之旅见行见心 ——香港科大EMBA郎酒庄园深度体验之旅
  17. 右手定则判断向量积的方向
  18. Python开发-面向对象编程-王大鹏-专题视频课程
  19. iphone铃声制作
  20. 天池比赛首次参加记录

热门文章

  1. 用c语言编程一个英尺转换器,PTA-基础编程题目厘米换算英尺英寸-C基础版
  2. va_list(可变参数函数的使用)
  3. ResNet论文翻译——中文版
  4. Python中pass是什么?
  5. 小米平板2刷哪个系统更流畅_Windows 10版小米平板2简测:流畅度不及自家MIUI版...
  6. [RK3288][Android7.1]调试笔记 --- Settings设置WLAN热点支持遥控器弹出软键盘输入法
  7. 全球研究:持续绩效管理可提高竞争优势
  8. A Visual, Intuitive Guide to Imaginary Numbers
  9. U盘安装Windows 11正式版绕过TPM检查
  10. attribute和property的区别 (转载)