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

时间:2020-06-18 23:40:42

标签: java sql spring hibernate db2

我正在使用Spring Web应用程序,该应用程序使用休眠模式连接到DB2数据库。我试图通过减少数据库查询的数量来优化在星期三服务调用期间可能调用的服务方法。

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

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'
                )
        )
)

还是有更好的选择?

两个查询似乎都在大约相同的时间(<50ms)运行,但这可能取决于结果数据。我需要测试更多才能确定。

这两个查询的要点是它们中的一个替换了其他三个查询,在这些查询中,它们的结果数据用Java处理以获取所需的数据。

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

我觉得自己可能会浪费时间,因为表B和C的Java对象在表A的对象中是一对多的关系,并且无论如何它们都是通过休眠加载的。这意味着从长远来看,我可能永远都不会省钱。我的想法在这里正确吗?

谢谢!

1 个答案:

答案 0 :(得分: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)上建立索引。