嵌套查询优化

时间:2014-08-07 15:35:33

标签: mysql database

SELECT id
FROM `events` 
WHERE heading LIKE '%somestr%'
AND guests_since_start > 10
AND (SELECT COUNT(*)
FROM `submissions`
WHERE `submissions`.event_id = `events`.id)!=0;

目前此查询会崩溃我的服务器。我的想法是从事件表中获取所有id在提交表中具有相应行的事件(事件和提交由event_it链接。只要行数不为0,那么我希望显示这些记录

问题是events表有大约3,000条记录,而submissions表大约有290,000条。

对此事的任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:5)

直接加入会为您过滤并提高效率:

SELECT DISTINCT id
FROM `events` 
    INNER JOIN `submissions` 
    ON `submissions`.event_id = `events`.id
WHERE heading LIKE '%somestr%'
AND guests_since_start > 10

DISTINCT需要过滤掉重复项。这有点降低了效率(因为MySQL现在必须删除重复),但总的来说它会比任何子查询快得多。 submissions.event_idevents.id上的索引将有助于进一步发展。

答案 1 :(得分:1)

首先,我将查询重写为:

   SELECT e.id
     FROM events e
    WHERE e.heading LIKE '%somestr%'
      AND e.guests_since_start > 10
      AND EXISTS (SELECT 1 FROM submissions s WHERE s.event_id = e.id);

或者正如Matt S指出的那样(我相信他可能会稍快一点,但我更喜欢减少语法):

   SELECT DISTINCT e.id
     FROM events e
     JOIN submissions s
       ON s.event_id = e.id
    WHERE e.heading LIKE '%somestr%'
      AND e.guests_since_start > 10

你在提交时做了不必要的计数。

我还要确保我有索引(e.id,eguests_since_start)和(s.event_id)。