mysql explain预估剖析
http://www.cnblogs.com/LBSer/p/3333881.html
引子:
使用MySQL建立了一张表country,总共有才3121行记录。
但是使用explain select count(*) from country;的时候,发现行数rows达到6897,让我大吃一惊。
mysql> explain select count(*) from country;+----+-------------+---------+------+---------------+------+---------+------+------+-------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+------+-------+| 1 | SIMPLE | country | ALL | NULL | NULL | NULL | NULL | 6897 | NULL |+----+-------------+---------+------+---------------+------+---------+------+------+-------+
问题:为什么explain的结果和真实的结果运行不一致,并且产生这么大的误差?
针对这个问题,上网查了些资料,特此发博文总结下,当然自己也是刚刚使用mysql,有很多不了解的地方,希望多多指正。
一、explain是什么?
通过explain可以查看MySQL的执行计划,从而知道MySQL是如何处理我们的SQL语句。具体来说通过explain我们能得到一系列的关键信息,比如哪些索引被实际使用,查询了多少行等等。
explain使用Rows来告知我们数据库即将要阅读的行数,但是实际将要阅读的行数和explain所记载的将要阅读的行数可能会有差异,这是因为explain并没有真的去执行sql语句从而得出行数,而是进行了某种预估。
二、explain怎么预估行数
找了半天得知真相的我眼泪掉下来:http://lists.mysql.com/commits/115810
1)mysql-5.5之前
首先找到查询第一个记录所在的page(记为PLeft),统计PLeft里的记录数(记为Records_PLeft),之后找到最后一个记录所在的page(记为PRight),统计PRight的记录数(Records_PRight),之后将Records_PLeft与Records_PRight取平均,最后乘以总共的page数目(记为Page_Num)。公式如下:
Rows = ((Records_PLeft + Records_PRight)/2)*Page_Num
统计上讲这个预估方法是很有偏的。比如总共4个page:page1(999 records), page2(1 record), page3(1 record), page4(1 record),这样预估出来的Rows=((999+1)/2)*4 = 2000,然而实际上才总共才有1002个记录。
2)mysql-5.5之后
上述预估偏差大的关键在于有偏,而有偏的关键在于采样的page数太少了,事实上只采样了边界2个,新算法的思路很简单,增加采样数目,比如采样10个page,这样可以在一定程度上降低偏差。
具体来说,mysql除了边界2个外,还沿着左侧page往右连续查找8个page,如果总的page数目小于等于10个,那么预估的Rows和真实的Rows一致。
Rows = ((Records_PLeft + Records_P1 + Records_P2 + ... + Records_P8 + Records_PRight)/10)*Page_Num
上述方法只是在一定程度上缓解了有偏的问题,但是不准确还是存在的,事实上楼主的mysql版本是5.6版本,可见还是没有解决的很好。
三、思考
为什么是从左往右连续选8个page,而不是在首尾之间随机选择8个page,既然要缓解采样有偏的问题,那么随机选应该更好。猜想可能有两个原因:1)随机选择每次explain得到的Rows不一样,不方便应用;2)随机选会造成I/O开销,尤其是数据量大的时候,毕竟explain是希望能快速得到预估结果。
我觉得应该还有更好的算法,能实现explain效率与精度的tradeoff,希望大家能给出建议。
转载于:https://www.cnblogs.com/LBSer/p/3333881.html
mysql explain预估剖析相关推荐
- mysql explain不准确_mysql explain预估剖析
引子: 使用MySQL建立了一张表country,总共有才3121行记录. 但是使用explain select count(*) from country;的时候,发现行数rows达到6897,让我 ...
- MySQL - Explain深度剖析
文章目录 生猛干货 官方文档 Explain介绍 测试数据 explain 使用 explain重要列说明 id select_type simple primary subquery derived ...
- 9. MySQL EXPLAIN解析
专栏地址: MySQL系列文章专栏 文章目录 1. EXPLAIN简介 2. EXPLAIN输出格式 2.1 EXPLAIN 包含的列 2.2 id列 2.3 select_type SIMPlE P ...
- Mysql索引原理剖析与优化策略
Mysql索引原理剖析与优化策略 1.索引的本质 在⽣产环境中,随着数据量不断的增⻓,SQL执⾏速度会越来越慢,常⻅的⼿段就是通过索引来提升查询速度,那么究竟为什么要添加索引?应该如何正确添加索引? ...
- 简单了解SQL性能优化工具MySql Explain
点击上方蓝色字体,选择"设为星标" 优质文章,及时送达 写在前面 MySql Explain是对SQL进行性能优化不可或缺的工具,通过他我们可以对SQL进行一定的分析和性能优化,降 ...
- Mysql Explain 详解
Mysql Explain 详解 一.语法 explain < table_name > 例如: explain select * from t3 where id=3952602; 二. ...
- [转]MySQL Explain详解
在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有 ...
- mysql extended_explain之三:MYSQL EXPLAIN语句的extended 选项学习体会,分析诊断工具之二...
MySQL 的explain命令有一个extended选项,我想可以很多人都没有注意,因为它对命令的输出结果没有任何改变,只是增加了一个warning.这个 warning中显示了MySQL对SQL的 ...
- MYSQL:explain分析
mysql explain分析 通过explain可以知道mysql是如何处理语句,分析出查询或是表结构的性能瓶颈.通过expalin可以得到: 1. 表的读取顺序 2.表的读取操作的操作类型 3.哪 ...
最新文章
- 《预训练周刊》第19期:歧义短语的类量子语境性研究、自然语言处理中prompt方法的系统综述...
- html怎么让文本自动换行不,【HTML】让pre标签文本自动换行
- wampserver搭建本地服务器
- 更新网盘(云存储)功能需求,免费网盘需求,手机数据备份
- 中国K12教育行业运营动向及未来发展战略分析报告2022年版
- cmake编译mysql常用参数
- Showdoc使用——接口文档
- js学习(node.js环境)
- [河南省ACM省赛-第四届] 表达式求值(nyoj 305)
- Redis数据结构及内部编码
- 如何变更 Git 服务器 IP 地址以及变更后的解决方法
- 【操作系统安全】_Win7Win8系列提权漏洞
- 红外线人体感应灯arduino_Arduino 各种模块篇 人体红外感应模块 proximity sensor
- tinymce粘贴word图片问题解决
- 敏捷转型行动笔记:用户故事实践
- 前端——使用JavaScript(jQuery)通过身份证号获取籍贯、生日、年龄、性别
- MATLAB_心形线的创建
- r5 5500u和r5 5600u的区别 哪个好
- interrupt和park的区别
- 计算机网络功能及计算机网络分类
热门文章
- nodejs实践录:windows 10系统nodejs环境搭建
- 嵌入式Linux入门3:Linux服务器搭建
- onvif学习笔记5:onvif框架代码初步了解
- C宏的一个技巧:可变参数
- u-boot移植随笔:EEPROM移植及测试
- 【clickhouse】clickhouse配置多块磁盘
- 【Kafka】Kafka Producer整体架构概述及源码分析
- 【Java】Java Controller 每次只能一个请求 多线程 ReentrantLock
- 【JVM】JVM 调优之 -XX 参数
- 【Flink】Flink TimeServer 之 timerService().registerProcessingTimeTimer