1. MySQL COUNT() 性能问题深度解析
最近在监控短信发送系统时,发现一个棘手问题:当未发送短信量达到百万级别时,简单的SELECT COUNT(*) FROM sms WHERE state = 0查询竟然频繁超时。这引发了我对MySQL COUNT()底层原理的深入探究,今天就把这些发现和解决方案分享给大家。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. COUNT() 慢查询的本质原因
2.1 存储引擎的差异实现
MySQL的COUNT()性能问题根源在于不同存储引擎的实现差异:
- MyISAM引擎:维护了一个精确的计数器,直接读取
TABLE_ROWS即可,时间复杂度O(1) - InnoDB引擎:必须遍历索引树统计行数,时间复杂度O(n)
我们通过一个简单的测试可以验证这个差异:
sql复制-- 创建测试表
CREATE TABLE test_myisam (id INT) ENGINE=MyISAM;
CREATE TABLE test_innodb (id INT) ENGINE=InnoDB;
-- 插入100万数据
INSERT INTO test_myisam SELECT * FROM
(WITH RECURSIVE cte AS (
SELECT 1 AS n UNION ALL SELECT n+1 FROM cte WHERE n < 1000000
) SELECT n FROM cte) t;
INSERT INTO test_innodb SELECT * FROM test_myisam;
-- 执行COUNT对比
SELECT COUNT(*) FROM test_myisam; -- 0.002s
SELECT COUNT(*) FROM test_innodb; -- 1.873s
2.2 MVCC机制的影响
InnoDB的MVCC(多版本并发控制)实现才是真正的"内鬼"。由于要支持事务隔离级别,同一时刻不同事务看到的数据行数可能不同。例如:
| 时间点 | 事务A | 事务B |
|---|---|---|
| T1 | BEGIN | BEGIN |
| T2 | COUNT(*) → |
