优化简单的mysql查询

时间:2011-05-23 13:21:38

标签: mysql optimization

我有一个非常简单的查询:

SELECT cp.`id_connections`
FROM `connections_page` cp
WHERE cp.`time_end` IS NULL
AND TIME_TO_SEC(TIMEDIFF(NOW(), cp.`time_start`)) < 900
GROUP BY cp.`id_connections`

表格非常简单:

CREATE TABLE IF NOT EXISTS `ps_connections_page` (
`id_connections` int(10) unsigned NOT NULL,
`id_page` int(10) unsigned NOT NULL,
`time_start` datetime NOT NULL,
`time_end` datetime DEFAULT NULL,
PRIMARY KEY (`id_connections`,`id_page`,`time_start`),
KEY `time_end` (`time_end`),
KEY `id_connections` (`id_connections`),
KEY `id_page` (`id_page`),
KEY `time_start` (`time_start`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

大约 250万行需要2到6秒才能执行(mysql 5.1.54-log)

EXPLAIN EXTENDED 说:

id      select_type    table    type    possible_keys   key         key_len ref     rows    filtered    Extra
1       SIMPLE         cp       ref     time_end        time_end    9       const   1497890 100.00      Using where; Using temporary; Using filesort

查看执行计划,索引使用有问题,但我无法弄清楚。那么:我该如何加快查询 witohut更改数据结构(我可以更改查询和/或索引,但不能更改列)?

2 个答案:

答案 0 :(得分:2)

这部分:

TIME_TO_SEC(TIMEDIFF(NOW(), cp.`time_start`)) < 900

无法在time_start上使用索引,因为后者是表达式的一部分。如果您希望查询能够使用该索引,则需要相应地重写它:

time_start < something_constant

此外,您可以通过在几个where / group by字段中添加索引来获益:

key(time_start, time_end, id_connections)

答案 1 :(得分:0)

首先你不需要使用别名cp

第二,我会尝试做一个子选择来减少时间计算

尝试这个让我知道它是否有所作为

SELECT id_connections
FROM (SELECT id_connections FROM connections_page WHERE time_end IS NULL))
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), time_start)) < 900
GROUP BY id_connections