当前位置: 首页 > 面试题库 >

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

雍河
2023-03-14
问题内容

我有一个存储“主题”的数据库,每个主题都与一堆图像(=这些主题的屏幕快照)相关联。现在,我想显示最新的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

问题答案:

首先尝试此查询-

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



 类似资料:
  • 我在Mysql中有一个查询, 我已经完成了简单的查询转换为hibernate查询。我将所有pojo类绑定到表。请指导我如何将多个连接查询转换为一个hibernate查询。

  • 但是,我的查询生成器是错误的。它会显示错误消息 SQLState[42000]:语法错误或访问冲突:1064您的SQL语法中有错误;查看与您的MySQL server版本相对应的手册以获得正确的语法 和生成的SQL SQL:从左联接中选择.*(内联接对。=。和。=。和 谁能帮我解决我的问题?多谢了。

  • 任何帮助都将不胜感激!

  • 问题内容: 我对子查询的性能/连接另一个表有一些疑问 这是我的SQL,现在这个东西可以运行大约一百万次或更多。我的问题是什么会更快? 如果我更改为() 或者 如果我将’HelpTable’添加到中并在中进行联接? edit1 好吧,此脚本仅运行与r个人一样多的人。 我的程序有2个模块,一个模块填充,另一个模块传输数据。该程序确实将2个数据库合并在一起,因此有时会使用相同的Key。 现在,我正在研究

  • 问题内容: 我有一个在SQL中完美运行的查询,但是我有最糟糕的时间将其转换为linq。该表(下面的表1)保存了多种记录类型的状态更改。联接需要设置两个字段以创建有效联接:SubmissionId(状态所属的表的pk)和SubmissionTypeId(确定状态所属的表)。 我已经尝试过使用x.DefaultIfEmpty()中的y到x进行多次迭代,并且无法在正确的位置设置where子句。我需要从T

  • 我试图转换这个JPQL查询;