簡體   English   中英

如何加快或改進此查詢?

[英]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
      )

我想知道以下幾點:

  1. 有什么方法可以更快地執行這些操作,或者在一個查詢中獲取所有唯一 ID 的最新值?
  2. 由於該數據集的大小每隔幾個月就會翻一番,將相關 id 的最新值存儲在單獨的表中是否是一種更好的策略,因此獲取它們的操作強度較低? 因此,我將有一張表存儲歷史值,而另一張表總是只保存 300 個最新值。 這感覺像是某種設計違規,但也似乎是解決日益嚴重的問題的公平解決方案。

| 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM