我已经在wamp服务器上运行了一个mysql数据库,我正在使用它来对Flickr数据进行频繁的模式挖掘.在将数据加载到数据库的过程中,我运行了一个计数查询来确定我已经加载了多少图像.我很惊讶它耗时3分49秒
select count(*) from image;
Run Code Online (Sandbox Code Playgroud)
在一个单独的表"概念"中,我存储了用户提供图像的标签列表."概念"表上的类似查询耗时0.8秒.神秘之处在于两个表都有大约200,000行.select count(*) from image;返回283,890并select count(*) from concept;返回213,357.
这是每个表的描述

显然,"图像"表有更大的行.我认为根据这篇博文可能"图像"太大而无法保存在内存中,因此我还使用此答案中的代码测试了表格的大小.
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;
Run Code Online (Sandbox Code Playgroud)
"图像"是179.98 MB,"概念"是15.45 MB
我在具有64 GB RAM的计算机上运行mysql,因此这两个表都应该很容易适应.我错过了什么会减慢我的查询速度?我该如何解决?
在SELECT COUNT(*)InnDB表上执行时,MySQL必须扫描索引来计算行数.在这种情况下,您唯一的索引是主(聚簇)索引,因此MySQL会对其进行扫描.
对于聚簇索引,实际的表数据也存储在那里.不包括开销,你的image表每行大约是1973字节(我假设两个主键列都有一个单字节字符集).这是每(16k)页最多8条记录,所以大约35,486页.您的comcept表每行大约257个字节.那是每页大约63条记录,所以大约有3,386页.这是必须扫描的数据量的巨大差异.
它必须完全读取每个页面,因为页面可能不完整.
然后,性能方面,也许这些页面中的一些在内存中,而另一些则不在内存中.由于MySQL的15/16偏好,也存在一些边际差异,但上述所有数字都应视为近似值.
解
将二级索引添加到较大的表应该产生SELECT COUNT(*)与较小的表大致相同的性能.当然,要更新另一个索引,更新会慢一点.
为了提高性能,请缩短主键,因为二级索引包括索引列和完整主键.
如果只需要估计的行数,则可以使用rows以下某个值中的值,该值使用表统计信息而不是扫描索引:
SHOW TABLE STATUS LIKE 'image'
Run Code Online (Sandbox Code Playgroud)
要么
EXPLAIN SELECT COUNT(*) FROM image
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
993 次 |
| 最近记录: |