我有一个具有以下结构的表:
id widget_id value date_recorded
-----------------------------------------------
1 1 10 2019-10-12 12:00:15
2 2 15 2019-10-12 12:00:15
3 3 20 2019-10-12 12:00:15
4 4 50 2019-10-12 12:00:15
5 1 12 2019-10-15 00:05:15
6 2 19 2019-10-15 00:05:15
7 3 25 2019-10-15 00:05:15
8 4 75 2019-10-15 00:05:15
该表大约有500,000条记录,因为我们需要保留小部件值的历史数据。大约有三百种不同的唯一窗口小部件ID,每个ID的记录数量相同,因此每个ID的记录数不到1700条。
大多数时候,我们只需要获取给定ID或所有ID的最新值,但我发现查询所花的时间比预期的长,尤其是在遍历所有需要的ID时。
我尝试了以下两个查询:
第一个需要花费三百到五百个MS。总计超过三百条记录。
SELECT
widget_id,
value,
date_recorded
FROM widget_values
WHERE widget_id = 1
ORDER BY date_recorded DESC
LIMIT 1
这需要500毫秒或更长时间
SELECT
widget_id,
value,
date_recorded
FROM widget_values
WHERE widget_id = 1
AND date_recorded = (
SELECT
MAX(date_recorded)
FROM widget_values
WHERE widget_id = 1
)
我想知道以下情况:
| widget_values | CREATE TABLE `widget_values` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`widget_id` int(11) DEFAULT NULL,
`value` int(11) NOT NULL,
`date_recorded` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `widget_id` (`widget_id`),
KEY `value` (`value`),
KEY `date_recorded` (`date_recorded`),
CONSTRAINT `widget_amounts_one` FOREIGN KEY (`widget_id`) REFERENCES `widget_codes` (`widget_id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB
答案 0 :(得分:1)
第date_recorded
列是什么意思?如果仅是数据的创建时间,则可以使用列id
进行排序:
SELECT
widget_id,
value,
date_recorded
FROM widget_values
WHERE widget_id = 1
ORDER BY id DESC
LIMIT 1
这将命中主键索引。
答案 1 :(得分:0)
( widget_id , date_recorded )
上的多列索引将为您提供帮助。
拥有多个索引的主要缺点是,每次插入,更新,删除都要付出代价。
要优化对表的访问时,必须针对该表验证每个不同的查询,并查看索引是否正确。
一种可能的优化是删除列id
,并将widget_id , date_recorded
变成primary key
。因此,您将只有一个索引。如果其他表需要引用单个行,则此优化就没有意义,因为您将使用更多字节来存储引用widget_id , date_recorded
。
答案 2 :(得分:0)
除了在表上有索引外,您还可以尝试在下面的查询中提高性能-
SELECT
widget_id,
value,
date_recorded
FROM widget_values
WHERE widget_id = 1
ORDER BY date_recorded DESC
LIMIT 1;