MySQL RDS环境下SELECT DISTINCT语句异常运行行为分析
问题背景
我创建了一个2TB的MySQL RDS实例,导入了总容量1.5TB的2张表:
+----------+---------------------------+------------+ | Database | Table | Size in MB | +----------+---------------------------+------------+ | stam_db | owl | 1182043.00 | | stam_db | owl_owners | 393695.00 | +----------+---------------------------+------------+
实例规格为db.m6g.2xlarge,配置6000预配置IOPS。
我执行以下查询获取前10条无重复行(表内实际无重复行):
SELECT DISTINCT * FROM owl ORDER BY name LIMIT 10;
该查询运行2小时仍未结束,同时观测到以下指标异常:
- 可用存储空间以每分钟2.2GB的速度下降

- 写入IOPS骤升至每秒600-700

- 读取IOPS高达每秒约1850

- 总IOPS仅在2400-2500区间,远低于预配置的6000

- CPU利用率始终维持在个位数低位

疑问列表
- 为什么
SELECT DISTINCT语句会引发数据库大量写入? - 为什么
SELECT DISTINCT需要读取全表,而非仅获取前10行? - 为什么RDS未用满分配的6000 IOPS?总IOPS仅达分配量的40%左右。
问题解答
- 针对第一个疑问:大量写入是查询生成的临时表导致的,临时表的大小最高可达到原表的100%。
- 针对第二个疑问:所有需要排序阶段的查询大多需要依赖临时表,例如使用GROUP BY、ORDER BY或者DISTINCT的查询。这类查询分两个阶段执行:第一阶段收集全量数据存入临时表,第二阶段对临时表执行排序,完成排序后才能取到符合ORDER BY规则的前10行结果。因此即便是带LIMIT的排序查询,也需要先读取全表数据。
- 针对第三个疑问:MySQL创建临时表的代码效率存在瓶颈,无法充分利用全部6000 IOPS。
内容的提问来源于stack exchange,提问作者Gromit
相关产品推荐
相关产品推荐

