小编典典

如何将依赖子查询转换为联接以获得更好的性能?

sql

我有一个存储“主题”的数据库,每个主题都与一堆图像(=这些主题的屏幕快照)相关联。现在,我想显示最新的10个主题,对于每个主题,我只想从数据库中获取一张图像(ID最低的图像)。

当前,我的查询如下所示(我正在使用子查询):

SELECT DISTINCT 
  t.theme_id, t.theme_name, theme_date_last_modification, image_id, image_type

FROM 
  themes t, theme_images i

WHERE 
  i.theme_id = t.theme_id
  AND t.theme_status = 3
  AND t.theme_date_added < now( )
  AND i.image_id = (
    SELECT MIN( image_id )
    FROM theme_images ii
    WHERE ii.theme_id = t.theme_id 
  )

GROUP BY 
  t.theme_id

ORDER BY 
  t.theme_date_last_modification DESC

LIMIT 10

它可以工作,但是查询速度很慢。当我使用EXPLAIN时,我可以看到有一个“依赖子查询”。是否可以将此依赖子查询转换为某种可以通过mysql更快处理的联接?

PS:我的实际查询要复杂得多,并使用更多表。我已经尝试过尽可能简化它,以便您可以专注于性能问题的实际原因。

编辑:这是EXPLAIN的输出:

id  select_type         table   type    possible_keys              key       key_len   ref                 rows  Extra   
1   PRIMARY             t       index   PRIMARY,themes             themes    212       NULL                5846  Using where; Using index; Using temporary; Using filesort
1   PRIMARY             i       eq_ref  PRIMARY,theme_id,image_id  PRIMARY   4         func                1     Using where
2   DEPENDENT SUBQUERY  ii      ref     theme_id                   theme_id  4         themes.t.theme_id   6

阅读 152

收藏
2021-04-28

共1个答案

小编典典

首先尝试此查询-

SELECT
  t.*, ti1.*
FROM
  themes t
JOIN theme_images ti1
  ON ti1.theme_id = t.theme_id
JOIN (SELECT theme_id, MIN(image_id) image_id FROM theme_images GROUP BY theme_id) ti2
  ON ti1.theme_id = ti2.theme_id AND ti1.image_id = ti2.image_id
ORDER BY 
  t.theme_date_last_modification DESC
LIMIT 10

另一种解决方案-

SELECT
  t.*, ti.*
FROM
  themes t
JOIN (SELECT * FROM theme_images ORDER BY image_id) ti
  ON ti.theme_id = t.theme_id
GROUP BY
  theme_id 
ORDER BY 
  t.theme_date_last_modification DESC
LIMIT
  10

然后添加您的WHERE过滤器。

2021-04-28