为什么rows这么大,在mysql explain中---写在去acumg听讲座的前一夜

这周五下班前,发现了一个奇怪问题,大概是这个背景

一张表,结构为

Create Table: CREATE TABLE `out_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=Innodb AUTO_INCREMENT=36865 DEFAULT CHARSET=latin1

总共有37K rows的数据,数据大概是这样

+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
|  4 | D    |
|  5 | c    |
|  6 | c    |
|  7 | c    |
|  8 | c    |
|  9 | c    |
| 10 | a    |
+----+------+

运行了这个SQL

mysql> select id from out_table where id >10000  limit 1;
+-------+
| id    |
+-------+
| 10001 |
+-------+1 row in set (0.00 sec)

速度也很快。

可是在运行explain的时候

mysql> explain select id from out_table where id >10000  limit 1;
+----+-------------+-----------+-------+---------------+---------+---------+------+-------+--------------------------+
| id | select_type | table     | type  | possible_keys | key     | key_len | ref  | rows  | Extra                    |
+----+-------------+-----------+-------+---------------+---------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | out_table | range | PRIMARY       | PRIMARY | 4       | NULL | 26358 | Using where; Using index |
+----+-------------+-----------+-------+---------------+---------+---------+------+-------+--------------------------+

发现rows居然有,26358

查看MySQL官方文档,rows所代表的含义

Column Meaning
rows Estimate of rows to be examined

翻译过来就是,估计需要检测的行数。

可是从DBA的直觉来说,id字段为主键,且为自增属性,另外后面有个limit 1,那么无论如何rows应该不大于1才对。

那么是否explain没有考虑后面的limit 1呢?

继续运行SQL验证

mysql> explain select id from out_table where id >10000 ;
+----+-------------+-----------+-------+---------------+---------+---------+------+-------+--------------------------+
| id | select_type | table     | type  | possible_keys | key     | key_len | ref  | rows  | Extra                    |
+----+-------------+-----------+-------+---------------+---------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | out_table | range | PRIMARY       | PRIMARY | 4       | NULL | 26358 | Using where; Using index |
+----+-------------+-----------+-------+---------------+---------+---------+------+-------+--------------------------+

果然后面的limit 1根本不影响rows的值

那么这个rows是怎么算出来的呢?我们翻看下MySQL源码(以5.6.23为例)。

为了避免不擅长的大段落描述,我把几个关键的文件和函数粘贴出来。

文件 关键部分 下一步
sql/opt_explain_traditional.cc" push(&items, column_buffer.col_rows, nil) col_rows
sql/opt_explain.cc select->quick->records records
sql/opt_range.cc check_quick_select  

而check_quick_select的功能,在MySQL源码中的注释为

Calculate estimate of number records that will be retrieved by a range scan on given index using given SEL_ARG intervals tree.

翻译过来就是,这个方法仅仅根据给出的关于这个索引的条件和索引本身,来判断需要扫描多少行。显然limit 1和这个索引是没有直接关系的。

所以新姿势,get!

原文地址:https://www.cnblogs.com/youge-OneSQL/p/8542486.html

时间: 2024-10-09 22:29:02

为什么rows这么大,在mysql explain中---写在去acumg听讲座的前一夜的相关文章

mysql explain中的 “Select tables optimized away”

mysql explain中的 “Select tables optimized away” http://blog.chinaunix.net/uid-10449864-id-2956845.html2009年 今天在做SQL语句优化的时候,在explain的时候,有这样一个提示: mysql> explain SELECT max( up_start ) AS up_start FROM test WHERE up_start > '2008-01-19 00:00:00' and up_

mysql explain 中type的归纳

为了更好的理解连接类型(type),将根据查询条件的不同对连接类型进行简单归纳. 表定义如下: 1.id为主键 mysql> show create table key_id; +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------

MYSQL EXPLAIN 中的KEY_LEN的说明

对于explain extended 查看执行计划里面的一些信息作为一个DBA还是必须掌握的. 参考博文:http://www.cnblogs.com/xuanzhi201111/p/4554769.html 环境: MySQL5.6.36 默认字符集: utf8 一.前置回顾: 1.数值型的字段长度 字段类型   长度    UNSIGNED          SIGNED有符号型           适用场合 tinyint:    1bytes   2^8-1 0-255        

mysql explain 中key_len的计算

今天丁原问我mysql执行计划中的key_len是怎么计算得到的,当时还没有注意,在高性能的那本书讲到过这个值的计算,但是自己看执行计划的时候一直都没有太在意这个值,更不用说深讨这个值的计算了: ken_len表示索引使用的字节数,根据这个值,就可以判断索引使用情况,特别是在组合索引的时候,判断所有的索引字段都被查询用到. 在查看官方文档的时候,也没有发现详细的key_len的计算介绍,后来做了一些测试,在咨询了丁奇关于变长数据类型的值计算的时候,突然想到innodb 行的格式,在这里的计算中有

mysql explain中的type列含义和extra列的含义

很多朋友在用mysql进行调优的时候都肯定会用到explain来看select语句的执行情况,这里简单介绍结果中两个列的含义. 1 type列 官方的说法,说这列表示的是“访问类型”,更通俗一点就是:mysql找到需要的数据行的方式.一下就是从效率最差到最好顺序分别介绍下: All 这个就是所谓的全表扫描,没有用到任何的index,mysql就是从头到尾把整个表遍历一边,找到所需要的数据行.效率是最差的.如下图,这个表中的usertype不是索引,这个查询中没有用到任何索引,所以就出现了全表扫描

mysql explain中key_len的计算

ken_len表示索引使用的字节数,根据这个值,就可以判断索引使用情况,特别是在组合索引的时候,判断是否所有的索引字段都被查询用到. key_len显示了条件检索子句需要的索引长度,但 ORDER BY.GROUP BY 子句用到的索引则不计入 key_len 统计值: 关于 key_len 的计算规则: • 当索引字段为定长数据类型,比如:char,int,datetime,需要有是否为空的标记,这个标记需要占用1个字节:• 当索引字段为变长数据类型,比如:varchar,除了是否为空的标记外

MySQL Explain 结果解读与实践

Explain 结果解读与实践 基于 MySQL 5.0.67 ,存储引擎 MyISAM . 注:单独一行的"%%"及"`"表示分隔内容,就象分开"第一章""第二章". explain 可以分析 select 语句的执行,即 MySQL 的"执行计划": mysql> explain select 1; +----+-------------+-------+------+--------------

边够胆去问喎,讲昨晚值夜嘅系大夫人跟前凌嬷

春丽老实嘅道:「我家姐昨个唔当值,今个同喺大夫人跟前,我边够胆去问喎,讲昨晚值夜嘅系大夫人跟前凌嬷嬷,边个敢问凌嬷嬷啊?”其他几个丫鬟,感觉春丽讲嘅都有道理,边个食饱咗顶嘅到嗰阵仲敢去惹大夫人呀?一个僆妹弱弱嘅问道:“你哋话表小姐系真出咗咩?”呢班等级唔同嘅奴婢,对于呢个嘢好嘅贪得意同八卦,你一言我一语嘅,好快呢平时冷清嘅清花阁就如市一般嘅热闹! http://www.dianyuan.com/people/784972 身边嘅二等妹春柳,平时口最快,又系一个唔畀人嘅,讲出嘢又快又急,已经十四岁

MYSQL EXPLAIN执行计划命令详解(支持更新中)

本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 本篇是根据官网中的每个一点来翻译.举例.验证的:英语不好,所以有些话语未必准确,请自行查看官网,若有些点下面没有例子的是因为当时一下子没有想出那么多来,如果大家有遇上好的例子,欢迎在下面留言我持续更新 查看执行计划的关键EXPLAIN 版本MYSQL5.6,用到的库是官网例子sakila,自行下载导入 由于要把每个点都翻译出来,还需要举例,所以需要一定的时间