ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql – 为什么count(*)查询在某些表上变慢而在其他表上没有?

2019-06-12 04:02:17  阅读:303  来源: 互联网

标签:mysql wamp


我已经在wamp服务器上运行了一个mysql数据库,我正在使用它来对Flickr数据进行频繁的模式挖掘.在将数据加载到数据库的过程中,我运行了一个计数查询来确定我已经加载了多少图像.我很惊讶它耗时3分49秒

select count(*) from image;

在一个单独的表“概念”中,我存储了用户提供图像的标签列表. “概念”表上的类似查询耗时0.8秒.神秘之处在于两个表都有大约200,000行.从图像中选择计数(*);返回283,890并从概念中选择count(*);返回213,357.

这是每个表的描述

显然,“图像”表有更大的行.我认为也许“图像”太大而无法保存在基于this blog post的内存中,因此我还使用this answer中的代码测试了表的大小.

SELECT table_name AS "Tables", 
round(((data_length + index_length) / 1024 / 1024), 2) "Size in MB" 
FROM information_schema.TABLES 
WHERE table_schema = "$DB_NAME"
ORDER BY (data_length + index_length) DESC;

“图像”是179.98 MB,“概念”是15.45 MB

我在具有64 GB RAM的计算机上运行mysql,因此这两个表都应该很容易适应.我错过了什么会减慢我的查询速度?我该如何解决?

解决方法:

在InnDB表上执行SELECT COUNT(*)时,MySQL必须扫描索引来计算行数.在这种情况下,您唯一的索引是主(聚簇)索引,因此MySQL会对其进行扫描.

对于聚簇索引,实际的表数据也存储在那里.不包括开销,你的图像表大约是每行1973字节(我假设两个主键列都有一个单字节字符集).这是每(16k)页最多8条记录,所以大约35,486页.您的comcept表每行大约257个字节.那是每页大约63条记录,所以大约有3,386页.这是必须扫描的数据量的巨大差异.

它必须完全读取每个页面,因为页面可能不完整.

然后,性能方面,也许这些页面中的一些在内存中,而另一些则不在内存中.由于MySQL的15/16偏好,也存在一些边际差异,但上述所有数字都应视为近似值.

将二级索引添加到较大的表应该产生与较小的表大致相同的SELECT COUNT(*)性能.当然,要更新另一个索引,更新会慢一点.

为了提高性能,请缩短主键,因为二级索引包括索引列和完整主键.

如果您只需要估计的行数,则可以使用以下某个行中的行值,该值使用表统计信息而不是扫描索引:

SHOW TABLE STATUS LIKE 'image'

要么

EXPLAIN SELECT COUNT(*) FROM image

标签:mysql,wamp
来源: https://codeday.me/bug/20190612/1223264.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有