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

Mysql 如何将依赖子查询转换为联接以获得更好的性能?,mysql,sql,subquery,Mysql,Sql,Subquery,我有一个存储主题的数据库,每个主题都与一大堆图像相关联=这些主题的屏幕截图。现在我想显示最新的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.th

我有一个存储主题的数据库,每个主题都与一大堆图像相关联=这些主题的屏幕截图。现在我想显示最新的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
一种方法是首先限制主题表,然后连接到图像:

通过对主题主题状态、主题日期、上次修改、主题id、主题日期添加索引,限制子查询应该是有效的


我想你也有一个关于theme\u images theme\u id,image\u id的唯一索引。

首先尝试这个查询-

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过滤器。

如果添加解释计划和SHOW CREATE TABLE tablename的输出,效果会更好;对于这两个表。我添加了解释输出。此查询所需的时间与原始查询所需的时间完全相同。注:我必须在下方的选择部分添加,theme_id,以使您的查询工作。是的,它应该在那里-尝试另一种解决方案,看看第二个查询。我必须更正我自己的评论。我不知道一小时前我做了什么-也许我在测量查询的执行时间时提交了错误的查询,因为我的计算机上打开了太多的phpMyAdmin查询窗口?但是在第一次检查之后!再次查询我可以告诉你,它实际上比我以前的查询快3倍。仍然不是闪电般的快,但根据解释,至少依赖子查询已经消失了:-我选择了您的第一个查询作为最佳=最快的解决方案,并且它已经在我的网站上实现了。非常感谢你的帮助!在更改了查询图像->主题图像,图像id->主题图像中的一些输入错误后,我可以告诉您,即使在确保设置了您提到的索引后,您的查询速度仍比我的原始查询慢3倍。好奇。如果你删除主题和添加的日期,速度会慢吗?@KeyserSoze哦,我的糟糕,对不起。正在更正查询。在删除和添加主题_date_后仍然很慢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