Mysql查询语句优化一则
最近一直忙于开发业务系统,数据库从原来的Oracle被替换成了Mysql,但在实际线上运行中发现有条sql执行起来非常慢,更奇怪的是这句sql还会导致整个数据库性能下降。这个问题非常严重!该sql和表结构如下:
SELECT name
,COUNT(*) AS counts
,type
FROM entityNameTemp
WHERE postTime > '2011-06-01 00:00:00'
GROUP BY name
ORDER BY counts DESC
LIMIT 10
| entityNameTemp | CREATE TABLE `entityNameTemp` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(600) DEFAULT NULL COMMENT '人名或者机构名',
`type` enum('personName','organizationName') DEFAULT NULL COMMENT 'personName 人名;organizationName:机构名',
`postTime` timestamp NULL DEFAULT NULL COMMENT '发帖时间',
`createTime` timestamp NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=Innodb AUTO_INCREMENT=1931915 DEFAULT CHARSET=utf8 |
这是对一个百万级别的临时表,目的是做一下统计取排名前十的数据。先来查看一下执行计划:
+----+-------------+----------------+------+---------------+------+---------+------+---------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+------+---------------+------+---------+------+---------+----------------------------------------------+
| 1 | SIMPLE | entityNameTemp | ALL | NULL | NULL | NULL | NULL | 1735829 | Using where; Using temporary; Using filesort |
+----+-------------+----------------+------+---------------+------+---------+------+---------+----------------------------------------------+
无疑是用到了临时表以及排序,且没有用上索引。但mysql的执行计划实在很难定位具体问题。之前有查过mysql对临时文件的使用规则,主体思路是查看tmp_table_size参数,mysql会评估一下本次查询大概会需要用到的内存大小,如果小于该参数则会使用磁盘临时文件。但这个参数我已经改到了200m,但问题依旧。查看了一下,发现设置了参数但仍然使用了磁盘。查询发现Created_tmp_disk_tables参数在sql语句执行前后增加了1:
mysql> show status like '%tmp%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 2 |
| Created_tmp_files | 15 |
| Created_tmp_tables | 7 |
+-------------------------+-------+
这就非常奇怪了,因为我手动计算发现这些数据量绝对不会超过200m,理论上是应该要用内存临时表的。这只好拿出杀手锏,查看详细的执行计划。在命令行下依次执行1)set profiling = 1; 2)sql语句;3)show profile;就可以看到详细的时间消耗,另外可以用show profiles查看执行过的sql语句。当前sql语句执行情况分析如下:
mysql> show profile;
+--------------------------------+------------+
| Status &
相关新闻>>
- 发表评论
-
- 最新评论 更多>>