这些 SQL 查询是不是等效?哪个更好还是有更好的选择?

Posted

技术标签:

【中文标题】这些 SQL 查询是不是等效?哪个更好还是有更好的选择?【英文标题】:Are these SQL queries equivalent? And which is better or is there a better option?这些 SQL 查询是否等效?哪个更好还是有更好的选择? 【发布时间】:2020-06-18 23:40:42 【问题描述】:

我正在开发一个利用休眠连接到 DB2 数据库的 Spring Web 应用程序。我正在尝试通过减少数据库查询的数量来优化在周三服务调用期间可能会被调用的服务方法。

所以我的问题是这个查询是否

SELECT DISTINCT a.* FROM TABLE_A a
LEFT JOIN TABLE_B b ON a.ID = b.FK_ID 
LEFT JOIN TABLE_C c ON a.ID = c.FK_ID
LEFT JOIN TABLE_D d ON c.DATA_RQST_ID = d.ID
WHERE (b.REQUEST_ID = 1234 AND b.TYPE = 'TYPE_A')
OR (c.REQUEST_ID = 1234 AND (c.TYPE = 'TYPE_A' OR c.TYPE = 'TYPE_B'))

相当于/比这个查询更好

SELECT * FROM TABLE_A a 
WHERE  a.ID IN 
(
    SELECT b.FK_ID FROM  TABLE_B b 
    WHERE b.REQUEST_ID = 1234 AND eb.TYPE = 'TYPE_A' 
)
OR a.ID IN 
(
    SELECT c.FK_ID FROM TABLE_C 
    WHERE ( c.REQUEST_ID = 1234 AND c.TYPE = 'TYPE_A' )
    OR 
        (
            c.TYPE = 'TYPE_B' AND c.REQUEST_ID IN 
                (
                    SELECT d.ID FROM TABLE_D d 
                    WHERE d.REQUEST_ID = 1234 AND v.TYPE = 'TYPE_A'
                )
        )
)

还是有更好的选择?

两个查询似乎在同一时间(

这两个查询的目的是让其中一个查询替换其他三个查询,其中它们的结果数据在 Java 中处理以获得所需的数据。

我还必须能够将 SQL 查询转换为 HQL。我正在努力转换第一个查询。

我有一种感觉,我可能会浪费我的时间,因为表 B 和 C 的 java 对象在表 A 的对象中是一对多的关系,无论如何它们都是由休眠加载的。这意味着从长远来看,我可能不会随时储蓄。我这里的想法对吗?

谢谢!

【问题讨论】:

有一个很大的不同 - 在您的第一个查询中,引用 D 不是必需的(它是 LEFT JOIN-ed),而在第二个查询中它是必需的.考虑到第二个查询的读取方式,您似乎在第一个查询中遗漏了部分条件。是这样吗? @Clockwork-Muse 是的,就是这样。我在逻辑上犯了一个错误,但我认为我应该离开它,因为接受的答案使用了那个逻辑。 【参考方案1】:

如果我理解正确,exists 将是最好的解决方案:

SELECT a.*
FROM TABLE_A a
WHERE EXISTS (SELECT 1
              FROM TABLE_B b 
              WHERE a.ID = b.FK_ID AND b.REQUEST_ID = 1234 AND b.TYPE = 'TYPE_A'
             ) OR
      EXISTS (SELECT 1
              FROM TABLE_C c JOIN
                   TABLE_D d
                   ON c.DATA_RQST_ID = d.ID
              WHERE a.ID = c.FK_ID AND
                    c.REQUEST_ID = 1234 AND
                    (c.TYPE IN ('TYPE_A', 'TYPE_B'))
             );

一大收获就是删除了select distinct

然后为了提​​高性能,您需要在 table_b(fk_id, request_id, type_id)table_c(fk_id, request_id, type, DATA_RQST_ID)table_d(id) 上建立索引。

【讨论】:

谢谢戈登,我会试试看 我在第一个查询中犯了一个逻辑错误,所以我需要稍微修改一下您的查询。但是,我认为这将适用于我正在做的事情。再次感谢您的帮助。

以上是关于这些 SQL 查询是不是等效?哪个更好还是有更好的选择?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 查询 - 哪个性能更好?

SQl 查询中哪个更好的子查询或联接?

哪个更好?将结果存储在 Session 中还是重新查询数据库?

在 SQL 中使用视图是不是更好,或者我应该只在我的 C# 代码中使用查询[关闭]

Oracle SQL WITH 语句是不是比 subselect 更好 [关闭]

使用具有一个条件的 WHERE 子句运行 100 个 SQL 查询,还是使用具有 100 个条件的 WHERE 子句的一个查询更好?