MySQL 优化 之 Copying to tmp table on disk

项目中遇到了慢查询问题

 

Sql语句

SELECT
    sum(price) AS price,
    `member_id`
FROM
    `crm_upload`
GROUP BY
    member_id
ORDER BY
    price DESC
LIMIT 10;

Explain 之后的结果:

MariaDB [member]> explain SELECT sum(price) as price,`member_id` FROM `crm_upload` WHERE `status` = 1 AND `approved` = 1 AND `consume_time` > '2015-09-10'  GROUP BY member_id ORDER BY price desc LIMIT 10;
+------+-------------+------------+------+---------------+------+---------+------+--------+----------------------------------------------+
| id   | select_type | table      | type | possible_keys | key  | key_len | ref  | rows   | Extra                                        |
+------+-------------+------------+------+---------------+------+---------+------+--------+----------------------------------------------+
|    1 | SIMPLE      | crm_upload | ALL  | NULL          | NULL | NULL    | NULL | 310461 | Using where; Using temporary; Using filesort |
+------+-------------+------------+------+---------------+------+---------+------+--------+----------------------------------------------+
1 row in set (0.00 sec)

 

关于 Using temporary; 手册解释

To resolve the query, MySQL needs to create a temporary table to hold the result. This typically happens if the query 

contains GROUP BY and ORDER BY clauses that list columns differently.

大意是,需要一个临时表来暂存查询后的结果,经常会出现在Group By 或者 Order By 中

 

关于 Using filesort;手册解释

MySQL must do an extra pass to find out how to retrieve the rows in sorted order. The sort is done by going through all rows 
according to the join type and storing the sort key and pointer to the row for all rows that match the WHEREclause. The keys then are sorted
and the rows are retrieved in sorted order.

大意是 Mysql 如果想要正常的查找出排序中的数据,需要做一个额外的传递。这个排序将根据join的类型遍历所有的数据,并且存储排序的key。找出匹配到的where条件的数据。

 

show profile

 

MariaDB [member]> show profile;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000037 |
| Waiting for query cache lock   | 0.000008 |
| init                           | 0.000006 |
| checking query cache for query | 0.000103 |
| checking permissions           | 0.000011 |
| Opening tables                 | 0.000029 |
| After opening tables           | 0.000010 |
| System lock                    | 0.000008 |
| Table lock                     | 0.000007 |
| After opening tables           | 0.000012 |
| Waiting for query cache lock   | 0.000006 |
| After opening tables           | 0.000041 |
| init                           | 0.000044 |
| optimizing                     | 0.000016 |
| statistics                     | 0.000244 |
| preparing                      | 0.000116 |
| executing                      | 0.000015 |
| Copying to tmp table           | 0.000061 |
| Copying to tmp table           | 0.138350 |
| converting HEAP to Aria        | 0.003233 |
| Creating index                 | 0.000025 |
| Repair by sorting              | 0.020695 |
| Saving state                   | 0.000040 |
| Creating index                 | 0.000005 |
| converting HEAP to Aria        | 0.000070 |
| Copying to tmp table on disk   | 4.040516 |
| Sorting result                 | 0.020373 |
| Sending data                   | 0.000046 |
| end                            | 0.000003 |
| removing tmp table             | 0.000838 |
| end                            | 0.000013 |
| query end                      | 0.000008 |
| closing tables                 | 0.000010 |
| freeing items                  | 0.000006 |
| updating status                | 0.000003 |
| Waiting for query cache lock   | 0.000002 |
| updating status                | 0.000715 |
| Waiting for query cache lock   | 0.000015 |
| updating status                | 0.000002 |
| storing result in query cache  | 0.000014 |
| logging slow query             | 0.000053 |
| cleaning up                    | 0.000017 |
+--------------------------------+----------+

 

 

 

可以看到 

Copying to tmp table on disk 花费了大量的时间。

结果查找资料后 了解到 发现mysql可以通过变量tmp_table_size和max_heap_table_size来控制内存表大小上限,如果超过上限会将数据写到磁盘上,从而会有物理磁盘的读写操作,导致影响性能。

调整参数配置之后 就不会有这个问题了。

  • To set max_heap_table_size to 64M do the following:
    • SET max_heap_table_size = 1024 * 1024 * 64;
  • To set tmp_table_size to 32M do the following:
    • SET tmp_table_size = 1024 * 1024 * 32;

 

转载于:https://www.cnblogs.com/alin-qu/p/8092875.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值