簡體   English   中英

優化數據庫中大表的查詢(SQL)

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

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