简单查询缓慢
无论如何,要获得更好的性能。简单查询缓慢
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的关键。
任何帮助将不胜感激。
谢谢。
试试这个: 如果日期是不一样的,那么
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
希望它可以帮助
感谢您的回复我已经尝试过了,结果几乎相同:( – mybigman
根据您的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;
,我认为它是缓慢的,因为你有这么多的数据,你的SQL都必须经过所有的数据(不从整个数据集挑一个),所以index
不能帮助这里。
笔者建议选择是使用并行:
- 添加索引由@newtover
- 使用的建议12个线程来检索每个月的效果。
或者更简单:
只是预先计算出结果到另一个表, 查询时,从该表中查询。
我喜欢预先计算的想法值和存储在另一个表中,但问题是这些日期是随机的基于用户选择。他们也可以将过滤器应用到表中的其他列,这也会影响结果,所以我不认为它会成为可能吗?令我感到惊讶的是,对ORACLE DB的相同查询大约为500毫秒: - /奇怪还是什么? – mybigman
有一些设置可以调整,例如,如果您使用的是** innodb **,最重要的设置可能是'innodb_buffer_pool_size',大多数情况下您应该将大部分内存分配给它。 –
您应该解决此外部查询更改。
- 创建一个表来保存准备计算汇总每个过去一个月
- 砍下表的很多的大小。每年或每月或每行的另一个表格更改。
这些字段的类型是什么。你可以粘贴CREATE吗?你在这张桌上有多少条记录?速度有多慢,您可以粘贴执行时间吗? –
“fdyofmth”(本身)的索引将有所帮助。有一个吗? – wallyk
@NedretRecep我现在不在工作,所以我不能粘贴CREATE,但字段是“DATE - fdyofmth”和“INT - total_restored”。正如我所说,需要3秒才能显示结果,而在fdyofmth上的索引需要6秒 - 根据解释计划,此表中的总行数为752K。谢谢。 – mybigman