简单查询慢

时间:2011-11-24 06:32:46

标签: mysql

无论如何都可以从中获得更好的表现。

SELECT fdyofmth, SUM(total_restored) AS total_restored
FROM sum_restored
WHERE fdyofmth BETWEEN '2010-11-01' AND '2011-11-01'
GROUP BY fdyofmth
ORDER BY fdyofmth DESC

结果需要3秒。

+------------+----------------+
| fdyofmth   | total_restored |
+------------+----------------+
| 2011-11-01 |          39793 |
| 2011-10-01 |          52367 |
| 2011-09-01 |          52141 |
| 2011-08-01 |          56515 |
| 2011-07-01 |          54668 |
| 2011-06-01 |          54874 |
| 2011-05-01 |          60025 |
| 2011-04-01 |          60005 |
| 2011-03-01 |          63856 |
| 2011-02-01 |          64472 |
| 2011-01-01 |          58943 |
| 2010-12-01 |          57005 |
| 2010-11-01 |          55731 |
+------------+----------------+

EXPLAIN结果 -

+----+-------------+--------------+------+---------------+------+---------+------+--------+----------------------------------------------+
| id | select_type | table        | type | possible_keys | key  | key_len | ref  | rows   | Extra                                        |
+----+-------------+--------------+------+---------------+------+---------+------+--------+----------------------------------------------+
|  1 | SIMPLE      | sum_restored | ALL  | NULL          | NULL | NULL    | NULL | 752660 | Using where; Using temporary; Using filesort |
+----+-------------+--------------+------+---------------+------+---------+------+--------+----------------------------------------------+
1 row in set

我试过把一个fdyofmth的钥匙实际上放慢了两倍。

非常感谢任何帮助。

谢谢。

4 个答案:

答案 0 :(得分:1)

我认为它很慢,因为你有这么多的数据,你的sql必须遍历所有数据(不从整个数据集中选择一个),所以index在这里不能帮助。

我建议的选项是使用并行性:

  
      
  1. 按照@newtover
  2. 的建议添加索引   
  3. 使用12个线程来检索每个月的结果。
  4.   

甚至更简单:

  

只是将结果预先计算到另一个表中,   当查询时,从该表中查询。

答案 1 :(得分:0)

试试这个: 如果日期不一样,那么

SELECT fdyofmth, SUM(total_restored) AS total_restored
FROM sum_restored
WHERE fdyofmth >= '2010-11-01' AND fdyofmth <= '2011-12-01'
GROUP BY fdyofmth
ORDER BY fdyofmth DESC

希望有所帮助

答案 2 :(得分:0)

根据您的EXPLAIN结果,查询不使用任何索引。您需要在fdyofmth上设置索引:

ALTER TABLE sum_restored ADD INDEX fdyofmth_index (fdyofmth);

或另一个建议=):

SELECT
    SUM (IF(fdyofmth = '2010-11-01', total_restored, NULL)) as `2010-11-01`,
    SUM (IF(fdyofmth = '2010-12-01', total_restored, NULL)) as `2010-12-01`,
    SUM (IF(fdyofmth = '2011-01-01', total_restored, NULL)) as `2011-01-01`,
    SUM (IF(fdyofmth = '2011-02-01', total_restored, NULL)) as `2011-02-01`,
    SUM (IF(fdyofmth = '2011-03-01', total_restored, NULL)) as `2011-03-01`,
    SUM (IF(fdyofmth = '2011-04-01', total_restored, NULL)) as `2011-04-01`,
    SUM (IF(fdyofmth = '2011-05-01', total_restored, NULL)) as `2011-05-01`,
    SUM (IF(fdyofmth = '2011-06-01', total_restored, NULL)) as `2011-06-01`,
    SUM (IF(fdyofmth = '2011-07-01', total_restored, NULL)) as `2011-07-01`,
    SUM (IF(fdyofmth = '2011-08-01', total_restored, NULL)) as `2011-08-01`,
    SUM (IF(fdyofmth = '2011-09-01', total_restored, NULL)) as `2011-09-01`,
    SUM (IF(fdyofmth = '2011-10-01', total_restored, NULL)) as `2011-10-01`,
    SUM (IF(fdyofmth = '2011-11-01', total_restored, NULL)) as `2011-11-01`
FROM sum_restored;

答案 3 :(得分:0)

您应该解决此外部查询更改。

  • 创建另一个表格以保存每个过去一个月的现成计算摘要
  • 减少了很多桌子的大小。每年或每月或每行的另一个表格更改。