如何优化此MySQL查询,选择不在另一个表中的行

时间:2015-06-18 22:32:06

标签: mysql

我有这个问题:

SELECT * 
FROM
(
    SELECT
        IGN,
        MAX(aktualizacja) AS wywalony,
        DATEDIFF(CURDATE(),MAX(aktualizacja)) AS wywalony_dni_temu
    FROM dump_armijny
    GROUP BY IGN
) AS a
WHERE IGN NOT IN
(
    SELECT DISTINCT IGN
    FROM dump_armijny
    WHERE aktualizacja =
    (
        SELECT MAX(aktualizacja)
        FROM dump_armijny
    )
)
ORDER BY wywalony DESC

但是13k行表需要大约2秒钟,并且它增长得非常快,我该如何优化呢?

2 个答案:

答案 0 :(得分:0)

确保dump_armijny.IGN被编入索引。

答案 1 :(得分:0)

以下是您的查询:

SELECT a.*
FROM (SELECT IGN, MAX(aktualizacja) AS wywalony, 
             DATEDIFF(CURDATE(), MAX(aktualizacja)) AS wywalony_dni_temu
      FROM dump_armijny
      GROUP BY IGN
     ) a
WHERE IGN NOT IN (SELECT DISTINCT IGN
                  FROM dump_armijny
                  WHERE aktualizacja = (SELECT MAX(aktualizacja)
                                        FROM dump_armijny
                                       )
                 )
ORDER BY wywalony DESC;

通常,not existsnot in更优化,select distinct子查询中不需要in。我会写这样的查询:

SELECT IGN, MAX(aktualizacja) AS wywalony, 
       DATEDIFF(CURDATE(), MAX(aktualizacja)) AS wywalony_dni_temu
FROM dump_armijny a
WHERE NOT EXISTS (SELECT 1
                   FROM dump_armijny a2 JOIN
                        (SELECT MAX(aktualizacja) as maxa FROM dump_armijny) m
                        on aktualizacja = m.maxa
                   WHERE a.IGN = a2.IGN
                 )
GROUP BY IGN
ORDER BY wywalony DESC;

遵循查询的逻辑有点困难,但我认为这与以下内容相同:

SELECT IGN, MAX(aktualizacja) AS wywalony, 
       DATEDIFF(CURDATE(), MAX(aktualizacja)) AS wywalony_dni_temu
FROM dump_armijny a JOIN
     (SELECT MAX(aktualizacja) as maxa FROM dump_armijny) m
GROUP BY IGN
HAVING wywalony <> m.maxa
ORDER BY wywalony;

无论如何,您应该定义一些索引。 A&#34;必备&#34;是dump_armijny(aktualizacja)。对于not exists版本,您还需要dump_armijny(IGN, aktualizacja)