zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    [转贴]Linux内核LTS长期支持版生命周期
    【转贴】Debian 10 "buster" 正式发布
    [百度经验]重置组策略的方法
    【转贴】我对测试工作的一些认识
    【转贴】使用sar进行性能分析
    【转贴】龙芯内核发展策略 已经支持k8s
    【转贴】优秀的龙芯Docker虚拟机解决方案
    Windows 2016 安装单机版本Oracle ASM 的简单说明
    【转贴】中标麒麟操作系统(龙芯版)与360安全浏览器完成产品兼容性互认证测试
    AQTime教程
  • 原文地址:https://www.cnblogs.com/alin-qu/p/8092875.html
Copyright © 2011-2022 走看看