使用左联接和从联接表排序时,MySQL Query花费的时间太长

时间:2018-09-22 16:07:54

标签: mysql sql

我的查询运行非常快(大约0.2862秒):

SELECT title, godina,
       (SELECT zanrovi.zanr 
        FROM zanrovi
        WHERE filmovi.zanr=zanrovi.id
       ) AS zanr,
       imdb, ocjena, sd, hd, fhd, 3d ,
       (SELECT COUNT(film)
        FROM statistika
        WHERE film=filmovi.id
       ) AS skinuto
FROM filmovi LEFT JOIN
     zanrovi
     ON filmovi.podzanrovi=zanrovi.id
ORDER BY filmovi.id DESC
LIMIT 0, 32

所以我需要这个查询到ORDER BY skinuto

因此,我修改了上面的查询来这样做:

SELECT title, godina,
       (SELECT zanrovi.zanr
        FROM zanrovi
        WHERE filmovi.zanr=zanrovi.id
       ) AS zanr,
       imdb, ocjena, sd, hd, fhd, 3d,
       (SELECT COUNT(film)
        FROM statistika
        WHERE film=filmovi.id
       ) AS skinuto
FROM filmovi LEFT JOIN
     zanrovi
     ON filmovi.podzanrovi=zanrovi.id
ORDER BY skinuto DESC
LIMIT 0, 32

查询将在41.328秒内执行!所以这太长了...所以我看到如果我从另一个表中使用skinuto会有延迟,那么问题是如何按skinuto进行排序,以便查询能够按原样快速执行?

当我删除ORDER BY skinuto并替换为ORDER BY filmovi.id时,它执行得非常快(不到0.5秒),我需要按skinuto订购。我在代码中缺少什么?

谢谢。

1 个答案:

答案 0 :(得分:1)

首先,在引用多个表的查询中,应始终使用完全限定的列名。您的子查询应如下所示:

. . .
       (SELECT COUNT(s.film)
        FROM statistika s
        WHERE s.film = f.id
       ) AS skinuto
FROM filmovi f LEFT JOIN
     zanrovi z
     ON f.podzanrovi = z.id

这使查询更容易理解。

您可能无法提高性能。但是开始的地方是以下索引:

  • zanrovi(id, zanr)
  • statistika(film)

这将加快子查询的速度。

我还想知道是否需要对zanrovi进行外部联接。您正在子查询中使用它,因此很可疑。

如果这没什么用,请考虑在FROM子句中进行更多过滤。由于外部查询中的zanr,似乎JOIN的子查询也是不必要的:

SELECT title, godina, z.zanr,
       imdb, ocjena, sd, hd, fhd, 3d ,
       s.skinuto
FROM (SELECT s.film, COUNT(s.film) as skinuto
      FROM statistika s
      GROUP BY s.film
      ORDER BY skinuto DESC
      LIMIT 0, 32
     ) s LEFT JOIN
     filmovi f
     ON s.film = f.id LEFT JOIN
     zanrovi z
     ON f.podzanrovi = z.id
ORDER BY s.skinuto DESC;

这假设statistika中的所有电影都在filmovi中。