【发布时间】:2012-08-11 13:12:56
【问题描述】:
我有一个 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 使用索引进行查询,但无济于事。
这里是解释输出:
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 检索第一行和最后一行会更快吗?
非常感谢您的帮助!
【问题讨论】:
-
重复索引没有帮助。您可以向 MySQL 询问use a specific index。您可以尝试一个想法:为时间段创建一个(临时?)表,加入该表而不是硬编码范围
SELECT device_id, MAX(id) WHERE <time condition> GROUP BY device_id,然后将其连接回原始表以获得对应于每个id的totaldistance.这也可能允许您在单个查询中获取多个时段的数据。
标签: php mysql performance