开发者

optimizing simple mysql query

开发者 https://www.devze.com 2023-03-07 15:30 出处:网络
I have a very simple query: SELECT cp.`id_connections` FROM `connections_page` cp WHERE cp.`time_end` IS NULL

I have a very simple query:

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`

for a very simple table:

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;

with about 2.5 millions rows, and it takes between 2 and 6 seconds to execute (mysql 5.1.54-log)

and EXPLAIN EXTENDED says:

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

Looking at execution plan, there is something wrong with index usage, but I can't figure it out. So: how can I do to speed up this query witohut changing data str开发者_运维技巧ucture (I can change query and / or indexes, but not columns)?


This part:

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

Cannot use the index on time_start because the latter is part of the expression. If you want the query to be able to use that index, you'll need to rewrite it accordingly:

time_start < something_constant

Also, you might benefit by adding the index on several of the where/group by fields:

key(time_start, time_end, id_connections)


first you don't need to use alias cp

second I would try doing a sub select to reduce the time calculations

try this out let me know if it makes a difference

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
0

精彩评论

暂无评论...
验证码 换一张
取 消