• 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;
  • 相关阅读:
    通过引入SiteMesh的JSP标签库,解决Freemarker与SiteMesh整合时,自定义SiteMesh标签的问题
    我为什么要写FansUnion个人官网-BriefCMS-电子商务malling等系统
    我为什么要写FansUnion个人官网-BriefCMS-电子商务malling等系统
    天龙八部回归记
    天龙八部回归记
    到底要不要买彩票,纠结了
    到底要不要买彩票,纠结了
    与Boss大雷探讨JavaWeb开发、电商与网络安全
    与Boss大雷探讨JavaWeb开发、电商与网络安全
    Fiori里花瓣的动画效果实现原理
  • 原文地址:https://www.cnblogs.com/alin-qu/p/8092875.html
Copyright © 2020-2023  润新知