[英]How do I speed up or Improve this query?
我有一個具有以下結構的表:
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 條記錄,因為我們需要保留小部件值的歷史數據。 大約有 300 個不同的唯一小部件 id,每個 id 的記錄數量相等,因此每個 id 大約有 1700 條記錄。
大多數時候,我們只需要獲取給定 ID 或所有 ID 的最新值,但我發現查詢花費的時間比預期的要長,尤其是在遍歷所有需要的 ID 時。
我嘗試了以下兩個查詢:
第一個需要三百五百毫秒。 超過三百條記錄加起來。
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
列date_recorded
的含義是什么? 如果只是數據的創建時間,可以使用列id
進行排序:
SELECT
widget_id,
value,
date_recorded
FROM widget_values
WHERE widget_id = 1
ORDER BY id DESC
LIMIT 1
這將命中主鍵索引。
( widget_id, date_recorded )
上的多列索引將為您提供幫助。
擁有多個索引的主要缺點是每次插入、更新、刪除都會受到懲罰。
當您想要優化對表的訪問時,您必須針對該表驗證每個不同的查詢,並查看您是否擁有正確的索引。
一種可能的優化是刪除列id
,並將widget_id, date_recorded
轉換為primary key
。 所以你將只有一個索引。 如果其他表需要引用單行,則此優化可能無關緊要,因為您將使用更多字節來存儲引用widget_id, date_recorded
。
除了在你的表上有索引,你可以嘗試下面的查詢來提高性能 -
SELECT
widget_id,
value,
date_recorded
FROM widget_values
WHERE widget_id = 1
ORDER BY date_recorded DESC
LIMIT 1;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.