我还能做些什么来优化这个查询?

时间:2013-11-12 05:06:40

标签: mysql sql

场景:包含1.5到200万条记录的表

我需要执行删除旧记录的查询,条件中使用的唯一字段是日期。我已经为该字段添加了索引。

问题:查询执行时间太长(超过14分钟)。

这是我到目前为止所做的事情

mysql> create index idx_logs_log_date ON logs (log_date);
Query OK, 0 rows affected (9.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> EXPLAIN SELECT * from logs where log_date < "2013-09-11";
| id | select_type | table | type | possible_keys     | key  | key_len | ref  | row |Extra

+----+-------------+-------+------+-------------------+------+---------+------+-----+-----

|  1 | SIMPLE      | logs  | ALL  | idx_logs_log_date | NULL | NULL    | NULL | 1420480 | Using where |


1 row in set (0.00 sec)



mysql> delete from logs where log_date < "2013-09-11";

Query OK, 1163008 rows affected (14 min 20.87 sec)

我还尝试删除该索引并在该字段中添加一个键(当然会创建一个新索引),但响应时间没有改善。

所以,我的问题,您对如何改善响应时间有任何其他想法吗?

编辑:

mysql> SELECT COUNT(id) FROM logs WHERE log_date < "2013-09-14";
+-----------+
| COUNT(id) |
+-----------+
|   1182688 |
+-----------+
1 row in set (0.58 sec)

2 个答案:

答案 0 :(得分:3)

很可能不是过滤器速度慢,而是删除了行(通过测量SELECT COUNT(id) FROM logs WHERE log_date < "2013-09-14"所需的时间进行测试。)

要加快速度,您需要调整一些服务器设置。但是,如果您只是为最后的X时刻保留基于时间的日志,那么您可能希望查看基于日期的分区,这样您就可以在不再需要时删除该表。

答案 1 :(得分:1)

因为SELECT count(*) from logs where log_date >= "2013-09-11";返回253736,而SELECT * from logs where log_date < "2013-09-11";返回1163008,所以我推断该索引实际上正在降低性能。

DROP INDEX `idx_logs_log_date` ON logs;
delete from logs where log_date < "2013-09-11";
create index idx_logs_log_date ON logs (log_date);