[英]MySQL query with subquery to slow
我在同一數據庫上有兩個表Device
和EventData
; 這兩個表都具有accountID
和deviceID
列,它們也是主鍵。
在Device
表中,有一列名為linkDescription
。
我需要在EventData
表中復制一些行,在Device
表中復制其accountID
和deviceID
,並在linkDescription
列中linkDescription
一些文本。
例:
設備表
accountID DeviceID linkDescription
12345 5800 444
12345 5700 445
12345 5500 null <--literally null
12388 4400 555
12388 4450 555
EventData表
accountID DeviceID timestamp
12345 5800 123335544
12345 5700 123335544
12345 5500 123335544
12388 4400 123335544
12388 4450 123335544
12345 5800 123335548
12345 5700 123335549
12345 5500 123335549
12388 4400 123335545
12388 4450 123335546
現在,我需要在EventData
上復制一些行,並使用Device
表中的linkDescription
更改accountID
; 因此EventData
現在具有以下數據:
accountID DeviceID timestamp
12345 5800 123335544
12345 5700 123335544
12345 5500 123335544
12388 4400 123335544
12388 4450 123335544
12345 5800 123335548
12345 5700 123335549
12345 5500 123335549
12388 4400 123335545
12388 4450 123335546
444 5800 123335544 <-duplicated data with new accountID from here
445 5700 123335544
555 4400 123335544
555 4450 123335544
444 5800 123335548
445 5700 123335549
555 4400 123335545
555 4450 123335546
所以現在我正在測試以下查詢,它將成為更大的INSERT INTO
:
explain
select *
from EventData
where
EventData.accountID in (
select accountID
from Device
where Device.linkDescription > '0')
and EventData.deviceID in (
select deviceID
from Device
where Device.linkDescription> '0')
and timestamp > (unix_timestamp(now()-interval 20 minute));
但是速度很慢,並且EXPLAIN
命令顯示如下:
ID select_type table type posible_keys key key_len ref rows Extra
1 PRIMARY EventData ALL null null null null 47555718 Using where
3 DEPENDENT SUBQUERY Device ALL null null null null 8043 Using where
2 DEPENDENT SUBQUERY Device index_subquery PRIMARY PRIMARY 34 func 3 Using where
因此,至少就我所知,正在檢查整個表,這就是為什么這么慢。
我怎樣才能更快地完成自己想要的?
從您的問題中我不確定您要做什么,但是您應該使用JOIN
來加快速度。 您的SELECT
可能更像這樣寫:
SELECT EventData.accountID from
EventData
RIGHT JOIN Device
ON
(
(
Device.accountID = EventData.accountID
OR Device.deviceID = Event.deviceID
)
AND Device.linkDescription> '0'
AND timestamp > (unix_timestamp(now()-interval 20 minute))
);
您可能可以算出INSERT
從那里如何工作。
考慮使用JOIN而不是where
條件:
select ed.*
from
EventData as ed
inner join Device as d1 on ed.accountId = d1.accountId
inner join Device as d2 on ed.deviceId = d2.deviceId
where
d1.linkDescription > '0'
and d2.linkDescription > '0'
and ed.timestamp > (unix_timestamp(now()-interval 20 minute));
我在復制Device
表只是為了更正您的查詢。 如果必須同時滿足兩個條件,則只需使用Device
表一次:
select ed.*
from
EventData as ed
inner join Device as d on ed.accountId = d.accountId and ed.deviceId = d.deviceId
where
d.linkDescription > '0'
and d.linkDescription > '0'
and ed.timestamp > (unix_timestamp(now()-interval 20 minute));
希望這可以幫助
它不一定是您的子查詢,它很慢,它的主表是4,700萬行:
和時間戳>(unix_timestamp(now()-interval 20分鍾)));
在時間戳上添加索引。 那應該解決。 我將指出,子查詢和聯接在現代版本的mysql中在性能上沒有真正的區別。 連接更干凈,但更容易理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.