mysql explain不准确_mysql explain预估剖析「建议收藏」

mysql explain不准确_mysql explain预估剖析「建议收藏」引子:使用MySQL建立了一张表country,总共有才3121行记录。但是使用explainselectcount(*)fromcountry;的时候,发现行数rows达到6897,让我大吃一惊。mysql>explainselectcount(*)fromcountry;+—-+————-+———+——+————–…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

引子:

使用MySQL建立了一张表country,总共有才3121行记录。

但是使用explain select count(*) from country;的时候,发现行数rows达到6897,让我大吃一惊。

mysql> explain select count(*) fromcountry;+—-+————-+———+——+—————+——+———+——+——+——-+

| 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怎么预估行数

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://javaforall.net/180883.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • PhpSpreadsheet读取excel「建议收藏」

    PhpSpreadsheet读取excel「建议收藏」PhpSpreadsheet composerrequirephpoffice/phpspreadsheet支持的格式格式读写OpenDocumentFormat/OASIS(.ods)✓✓OfficeOpenXML(.xlsx)Excel2007andabove✓✓BIFF8(.xls)Excel97anda…

    2022年9月17日
    2
  • Navicat15 注册激活码【最新永久激活】「建议收藏」

    (Navicat15 注册激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月27日
    2.0K
  • sort函数对vector排序_sort函数对结构体数组排序

    sort函数对vector排序_sort函数对结构体数组排序一、遇到问题:今天写代码的是遇到想对vector进行排序的问题,隐约记得std::sort函数是可以对vector进行排序的,但是这次需要排序的vector中压的是自己定义的结构体(元素大于等于2),想以其中某一个元素进行正序或逆序排序,则不能直接使用sort函数。二、解决方案:在网上找资料的过程中,看到http://blog.csdn.net/aguisy/article/d

    2022年8月12日
    6
  • 不一样的春节思维导图的内容_电学思维导图

    不一样的春节思维导图的内容_电学思维导图春节是我国四大传统节日之一,可以算是历史之悠久。但随着社会的发展,春节期间的年味渐渐的没那么浓烈了,以前大家聚在一起守岁、放鞭炮等,而现在大多数人都是抱着电子产品谁也不搭理谁。以往的习俗简而又简,后出

    2022年8月1日
    8
  • 因工作站与主要域间的信任关系失败而导致请求失败_此工作站和域控不信任

    因工作站与主要域间的信任关系失败而导致请求失败_此工作站和域控不信任在服务器的日志上,这个错误应该大家都不陌生了,错误的特征,我给大致描述一下:在域中总是会有计算机由于某种原因,导致计算机账户的密码无法和lsasecret同步系统会在计算机登陆到域的时候,提示已经丢失域的信任关系。日志大致如下:EventID:5SourceNETLOGONType  ErrorDescription  Thesessionsetupfromth…

    2022年10月18日
    3
  • 快速排序quicksort_快速排序的原理

    快速排序quicksort_快速排序的原理一、简介快速排序是(Quicksort)是对冒泡排序的一种改进,是非常重要且应用比较广泛的一种高效率排序算法。二、算法思路快速排序是通过多次比较和交换来实现排序,在一趟排序中把将要排序的数据分成两个独立的部分,对这两部分进行排序使得其中一部分所有数据比另一部分都要小,然后继续递归排序这两部分,最终实现所有数据有序。大致步骤如下:首先设置一个分界值也就是基准值又是也称为监视哨,通过该分界值将数据分割成两部分。将大于或等于分界值的数据集中到右边,小于分界值的数据集中到左边。一趟排序过后,左边部

    2022年8月12日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号