数据库中的统计信息在差异(准确)水平上描写了表中数据的漫衍环境,执行打算通过统计信息获取切合查询条件的数据巨细(行数),来指导执行打算的生成。
在以Oracle和SQLServer为代表的贸易数据库,和以开源的PostgreSQL为代表的数据库中,直方图是统计信息的一个重要构成部门。
在生成执行打算的时候,通过统计信息以及统计信息的直方图来预估切合条件的数据行数,从而影响执行打算的生成。
统计信息对执行打算的影响,详细表此刻:索引的查找与扫描,多表毗连时表之间的驱动顺序,表之间的JOIN方法,以及对sql查询语句的资源分派等等。
可是在MySQL数据库中,执行打算的方法相对简朴,表之间的JOIN只有LOOPJOIN一种方法,且没有并行执行打算等,也就说通过预估功效集的行数对执行打算的影响有限。
可是对付某些环境,依旧需要预估的方法来指导执行打算的生成,昆山软件开发,
好比常见的多表毗连时驱动顺序,大都环境下是小表驱动大表(不完全必然)的方法来实现查询的,因此MySQL中一样需要预估来指导执行打算的生成。
不外MySQL中的统计信息相对来说简朴许多,只有一个cardinality信息来预估索引的选择性(show index from table),
索引统计信息不包括直方图的信息,非索引列也不会生成直方图,也就是无法通过直方图来预估查询数据的巨细,mysql是通过其他方法来实现预估的。
对付有直方图的数据来说,直方图为预估提供了重要的依据,对付没有直方图的MySQL,执行打算是如何预估的?预估的精确性有如何?
笔者在研究这个问题的时候,一开始也碰着不少迷惑的处所,照旧看了博客园大神的问题才得以释惑,后头会给出链接。
首先通过例子,通过一个很是简朴的查询来调查一个有意思的现象。
新建测试表,测试表如下:
create table test_statistics ( id int auto_increment primary key, col2 varchar(200), col3 varchar(200), create_date datetime, index idx_create_date(create_date) )ENGINE=InnoDB;
存储进程通过轮回插入数据,挪用存储进程生成100W行数据(100W行的数据,在实际应用中已经是一个很是小的数据量了),create_date字段上生成一个范畴之内的随机时间。
CREATE DEFINER=`root`@`%` PROCEDURE `p_insert_test_data`( IN `loop_count` INT ) BEGIN declare i int; while (loop_count>0) do insert into test_statistics(col2,col3,create_date) values (uuid(),uuid(), DATE_ADD(sysdate(), INTERVAL -rand()*2400 hour)); set loop_count = loop_count -1; end while; END
写入测试数据完成之后,举办如下两个查询做测试。
简朴地利用select count(1)的来做测试
首先看第一个查询:查询的时间范畴是: where create_date>’2017-11-01 12:00:00′ and create_date<’2017-11-01 16:00:00′
可以发明:explain预估的行数,与实际行数完全一致。
昆山软件定制开拓 供了重要的依据" src="http://www.importnew.com/https:/images2017.cnblogs.com/blog/380271/201802/380271-20180205221541310-406698026.png" width="886" height="308" />
继承第二个查询,扩大查询的时间范畴,查询的时间范畴是:where create_date>’2017-11-01 12:00:00′ and create_date<’2017-11-03 16:00:00′
可以发明,此时的explain执行打算的预估,与实际行数呈现了严重的毛病
昆山软件定制开拓 供了重要的依据" src="http://www.importnew.com/https:/images2017.cnblogs.com/blog/380271/201802/380271-20180205221827810-827372185.png" width="890" height="306" />
为什么第一个查询做到了准确的预估,而第二个查询的预估呈现严重的毛病?
这一点要从预估的计较方法入手来说。
首先,第一个查询和第二个查询,独一的差异是,第二个查询的时间范畴放宽了,昆山软件开发,为什么时间放宽之后,执行打算的预估的精确性就大大下降?
既然是“预估”,就必然是存在误差,只不外是误差大与小的问题,误差的大下与详细的预估的方法有关。
任何预估的实现,都是以一种在差异水平上“以偏概全”的方法举办的,好比SQL Server是以对相关数据page的通过某种百分比来取样,然后存储在直方图中做预估依据的。
虽然,这种“以偏概全”的预估方法,是在机能与准确度之间衡量折中的功效.
在思量收集统计信息对机能和资源影响的前提下,预预计策各类方法可能价钱尽大概淘汰对预估发生误差的因素,关于直方图的生成这里不细说。
对付没有直方图的MySQL,它是是在执行的时候,通过扫描切合查询条件的部门数据页后做预估统计的.
MySQL是在查询的时候,直接对查询条件范畴内的数据页,取必然比例样本做统计之后预估的,可是这里取样的数据页面有必然的限制,不会无限制取样做统计预估。
假如切合条件的数据页超出了预定的范畴,则会取部门页举办预估,而不是全部页(为什么不是全部样做统计预估,原因就不消说了吧)。