簡體   English   中英

MySQL查詢與子查詢減慢

[英]MySQL query with subquery to slow

我在同一數據庫上有兩個表DeviceEventData 這兩個表都具有accountIDdeviceID列,它們也是主鍵。

Device表中,有一列名為linkDescription

我需要在EventData表中復制一些行,在Device表中復制其accountIDdeviceID ,並在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.

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