带子查询的MySQL查询速度慢

时间:2013-05-07 18:24:46

标签: mysql

我在同一个数据库DeviceEventData上有两个表;两个表都有accountIDdeviceID列,它们也是主键。

Device表格中有一个名为linkDescription的列。

我需要在表EventData中复制一些行,accountIDdeviceIDDevice表中,在{{1}列中有一些文字}。

示例:

设备表

linkDescription

EventData表

accountID  DeviceID linkDescription
12345       5800      444
12345       5700      445
12345       5500      null <--literally null
12388       4400      555
12388       4450      555

现在我需要在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表中的accountID更改linkDescription;所以Device现在有以下数据:

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

所以,至少我理解的是检查整个表格,这就是为什么这么慢。

我怎样才能更快地做我想做的事?

3 个答案:

答案 0 :(得分:0)

我不确定你的问题是什么,但你应该使用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如何在那里发挥作用。

答案 1 :(得分:0)

考虑使用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));

希望这有帮助

答案 2 :(得分:0)

它的子查询不一定很慢,它的主表是4700万行:

和时间戳&gt; (unix_timestamp(now() - interval 20分钟));

在时间戳上添加索引。那应该解决它。我将指出子查询和连接在现代版本的mysql中的性能没有真正的区别。然而,联接更清晰,更容易理解。