我有一个相当大的表(1,8GB,25M 记录),每个重要列都有索引(我使用 WHERE 或其他选择器)。引擎是 MyISAM,我听说有人建议切换到 InnoDB,但许多其他人说 MyISAM 在计算大量数据时速度更快(而 InnoDB 更适合安全事务)。
现在,有时,我会做一组简单的统计查询(所以我知道我们的立场):
(A) SELECT COUNT(username) FROM superLargeTable
(B) SELECT COUNT(username) FROM superLargeTable WHERE firstname IS NOT NULL
(C) SELECT COUNT(username) FROM superLargeTable WHERE firstname IS NULL
如果最近更新了表(并且缓存无效),这些是慢查询日志测量的查询时间:
A:71 秒(锁定:0 秒)(行:1) B:47 秒(锁定:0 秒)(行:1) C:20 秒(锁定:0 秒)(行:1)
显然,第二次运行(因为它被缓存了)会产生几乎即时的数据。
我对所有相关列都有索引(几乎所有列都有索引)。我仍然接受建议,说许多列上的索引是非常糟糕的设计,另一方面,我完全需要它,因为否则查询将全部超时。
我确实有很多突发类型的插入和更新,以不规则的时间间隔在表上触发(有时每分钟一次,最多 5000 次快速插入/更新),有时间隔几分钟。
数据需要同步,所以我不能拆分为只读从属设备并使用它。
知道为什么一个简单的 COUNT 需要这么长时间吗?是否有一个秘密的替代命令可以告诉我一行中有多少条记录,并且有一个特定的标准?
真的很纳闷。服务器是 8GHz、8/16GB RAM、160GB 磁盘(10% 左右正在使用),查询都在本地运行,而不是通过网络传输。
如果需要,愿意帮助提供更多数据/信息。
编辑 1:查询 A 的 EXPLAIN 命令返回:
select_type=SIMPLE
type=index
possible_keys=NULL
key=followers (this is the actual username column in the imaginary query above)
key_len=9
ref=NULL
rows=24408162
Extra=Using index
编辑 2:@theHe 推荐了一个很棒的工具:mysqltuner.pl - 这是结果(问题):
[!!] Total fragmented tables: 15
[!!] Maximum possible memory usage: 30.7G (767% of installed RAM)
[!!] Query cache efficiency: 8.6% (5M cached / 59M selects)
[!!] Joins performed without indexes: 19031
[!!] Temporary tables created on disk: 48% (993K on disk / 2M total)
[!!] Table cache hit rate: 0% (64 open / 27K opened)
这些是建议:
-------- Recommendations -----------------------------------------------------
General recommendations:
Run OPTIMIZE TABLE to defragment tables for better performance
Reduce your overall MySQL memory footprint for system stability
Adjust your join queries to always utilize indexes
When making adjustments, make tmp_table_size/max_heap_table_size equal
Reduce your SELECT DISTINCT queries without LIMIT clauses
Increase table_cache gradually to avoid file descriptor limits
Variables to adjust:
*** MySQL's maximum memory usage is dangerously high ***
*** Add RAM before increasing MySQL buffer variables ***
query_cache_limit (> 10M, or use smaller result sets)
join_buffer_size (> 128.0K, or always use indexes with joins)
tmp_table_size (> 32M)
max_heap_table_size (> 16M)
table_cache (> 64)