[英]How can I make this MySQL Query faster?
我有一个MySQL查询,有时需要1秒钟以上的时间来执行。 查询如下:
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 / DBA专家,但是那里的索引似乎有点过分了。 通常,我将确保对要查询或连接的列进行索引; 因此,您需要一个用于deviceid和gpsdatetime。 每个查询1秒并不可怕,因此您在这里的返回可能会受到限制。
2.)尝试消除循环。 如果您要返回数据库25次; 您将仅通过打开/关闭连接等来产生开销。 一次进入数据库,然后使用PHP处理结果以获得所需的最终数据可能会更快。
我不能说出您的确切情况,但是我发现查询所有行并忽略除第一个之外的所有行都比limit语句快(尽管这是使用SQL Server)。 这很容易-删除您的limit 1子句并尝试一下。 然后,您可以使用PHP读取第一个和最后一个,从而减少MySQL实例的负载(即,运行单个查询而不是2)。
顺便说一句,为什么您有两个具有相同列的唯一键-id_deviceid和deviceid_id? 删除所有索引,然后再次添加它们,对于快速数据库,您确实确实希望尽可能少的索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.