设为首页 加入收藏

TOP

Mysql查询语句优化一则(一)
2014-11-24 03:07:26 来源: 作者: 【 】 浏览:5
Tags: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 | Duration |

+--------------------------------+------------+

| starting | 0.000023 |

| checking query cache for query | 0.000069 |

| Opening tables | 0.000016 |

| System lock | 0.000008 |

| Table lock | 0.000036 |

| init | 0.000030 |

| optimizing | 0.000011 |

| statistics | 0.000018 |

| preparing | 0.000014 |

| Creating tmp table | 0.000265 |

| executing | 0.000008 |

| Copying to tmp table | 165.312749 |

| Sorting result | 0.258847 |

| Sending data | 0.000094 |

| end | 0.000007 |

| removing tmp table | 0.302258 |

| end | 0.000026 |

| query end

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇MySQL中多表删除方法 下一篇mysql 双机热备份 master-master

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·请问微信4.0版本xwec (2025-12-24 22:48:42)
·电脑NVIDIA的文件夹 (2025-12-24 22:48:40)
·如何看待微信新版本 (2025-12-24 22:48:37)
·C语言中如何将结构体 (2025-12-24 22:20:09)
·纯C语言结构体成员变 (2025-12-24 22:20:06)