2012-08-11 71 views
0

我有一个MySQL查询有时需要1秒钟才能执行。查询如下:如何使此MySQL查询更快?

SELECT `id`,`totaldistance` FROM `alltrackers` WHERE `deviceid`='FT_99000083426364' AND (`gpsdatetime` BETWEEN 1341100800 AND 1342483200) ORDER BY `id` DESC LIMIT 1 

该查询运行在一个循环中,以检索月份某些日子的行等。这将导致页面接管25秒有时加载...

表结构如下:

CREATE TABLE IF NOT EXISTS `alltrackers` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `deviceid` varchar(50) NOT NULL, 
    `lat` double NOT NULL, 
    `long` double NOT NULL, 
    `gpsdatetime` int(11) NOT NULL, 
    `version` int(11) DEFAULT NULL, 
    `totaldistance` int(11) NOT NULL DEFAULT '0', 
    `distanceprocessed` tinyint(1) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id_deviceid` (`id`,`deviceid`), 
    UNIQUE KEY `deviceid_id` (`deviceid`,`id`), 
    KEY `deviceid` (`deviceid`), 
    KEY `deviceid_gpsdatetime` (`deviceid`,`gpsdatetime`), 
    KEY `gpsdatetime_deviceid` (`gpsdatetime`,`deviceid`), 
    KEY `gpsdatetime` (`gpsdatetime`), 
    KEY `id_deviceid_gpsdatetime` (`id`,`deviceid`,`gpsdatetime`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=677242 ; 

我已经加入各项指标的组合(请告诉我哪删除)在为了试图让MySQL使用索引进行查询,但无济于事。

这里是EXPLAIN输出:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE alltrackers index deviceid_id,deviceid,deviceid_gpsdatetime,gpsdatet... PRIMARY 4 NULL 677238 Using where 

我使用ORDER BY ASC/DESC LIMIT 1的原因是因为我需要查询的第一行和最后一行。运行没有LIMIT 1的查询并使用PHP检索第一行和最后一行会更快吗?

非常感谢您的帮助!

+1

重复索引不起作用。您可以要求MySQL [使用特定索引](http://dev.mysql.com/doc/refman/5.5/en/index-hints.html)。你可以尝试一个想法:为时间段创建一个(临时?)表,加入那个表而不是硬编码范围,'SELECT device_id,MAX(id)WHERE

回答

0

我不能说你的确切情况,但我发现查询所有行并忽略除第一个以外的所有行比限制语句(尽管这是使用SQL Server)更快。它很容易做 - 删除您的限制1条款,并试一试。然后,您可以使用PHP读取第一个和最后一个,从而减少MySQL实例的负载(即运行单个查询而不是2个)。顺便说一句,为什么你有2个唯一的键与他们相同的列 - id_deviceid和deviceid_id?删除所有索引,然后再次将它们添加回来,对于快速数据库,您确实需要尽可能少的索引。

+0

谢谢。我删除了限制,并使用mysql_seek_row命令读取第一个和最后一个结果。 LIMIT导致查询运行缓慢并忽略索引... – SeBsZ 2012-08-13 11:46:51

0

夫妇的事情,我能想到的把我的头顶部:

1)我没有任何延伸一个MySQL/DBA大师,但指数似乎好像有点矫枉过正。通常我会确保查询或加入的列被索引;所以你想要一个deviceid和gpsdatetime。每个查询1秒不是可怕的,所以你在这里的回报可能是有限的。

2.)尝试消除循环。如果你要回到数据库25次;你只需要打开/关闭连接等。一次访问数据库可能会更快,然后使用PHP处理结果以获取所需的最终数据。