[英]Optimize the query for a large table in database (SQL)
我正在嘗試優化大型事件表(1000 萬+行)上的 sql 查詢以進行日期范圍搜索。 我已經在這個表上有唯一的索引(蓋子、做、測量、日期)。下面的查詢試圖在日期列中每 2 秒間隔獲取三種測量類型(千瓦、電流和電壓)的事件:
SELECT *, FLOOR(UNIX_TIMESTAMP(date)/2) AS timekey
from events
WHERE lid = 1
and did = 1
and measurement IN ("Voltage")
group by timekey
UNION
SELECT *, FLOOR(UNIX_TIMESTAMP(date)/2) AS timekey
from events
WHERE lid = 1
and did = 1
and measurement IN ("Current")
group by timekey
UNION
SELECT *, FLOOR(UNIX_TIMESTAMP(date)/2) AS timekey
from events
WHERE lid = 1
and did = 1
and measurement IN ("Kilowatts")
group by timekey
這是我要查找的表。
=============================================================
id | lid | did | measurement | date
=============================================================
1 | 1 | 1 | Kilowatts | 2020-04-27 00:00:00
=============================================================
2 | 1 | 1 | Current | 2020-04-27 00:00:00
=============================================================
3 | 1 | 1 | Voltage | 2020-04-27 00:00:00
=============================================================
4 | 1 | 1 | Kilowatts | 2020-04-27 00:00:01
=============================================================
5 | 1 | 1 | Current | 2020-04-27 00:00:01
=============================================================
6 | 1 | 1 | Voltage | 2020-04-27 00:00:01
=============================================================
7 | 1 | 1 | Kilowatts | 2020-04-27 00:00:02
=============================================================
8 | 1 | 1 | Current | 2020-04-27 00:00:02
=============================================================
9 | 1 | 1 | Voltage | 2020-04-27 00:00:02
預期結果是檢索日期等於 2020-04-27 00:00:00 和 2020-04-27 00:00:02 的所有數據。 上面提供的查詢按預期工作。 但是我正在使用 UNION 在桌子上查找不同的測量值,我相信這可能不是最佳方法。
任何 SQL 專家可以幫我解決我必須提高性能的查詢嗎?
對於每次測量,您每秒都有一條記錄,並且您希望每兩秒記錄一條記錄。
你可以試試:
select *
from events
where
lid = 1
and did = 1
and measurement IN ('Voltage', 'Current')
and extract(second from date) % 2 = 0
這將是具有偶數第二部分的 select 記錄。
或者,如果您總是每秒有一條記錄,則另一個選項是row_number()
(這需要 MySQL 8.0):
select *
from (
select
e.*,
row_number() over(partition by measurement order by date) rn
from events
where
lid = 1
and did = 1
and measurement IN ('Voltage', 'Current')
) t
where rn % 2 = 1
不過,這比之前的查詢准確度要低一些。
您的查詢實際上是三個查詢合二為一。 幸運的是,它們都是基於相似列的 select 行數據。 如果要使此查詢快速運行,可以添加以下索引:
create index ix1 on events (lid, did, measurement);
除了上述建議之外,更改PRIMARY KEY
會給您帶來更多性能:
PRIMARY KEY(lid, did, date, measurement)
並折騰id
。
警告,如果兩個讀數以完全相同的“秒”出現,則可能會出現問題。 如果一個讀數在時鍾滴答之后進入,而下一個讀數在下一個滴答之前進入,則很容易發生這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.