使用 OR 子句的 SQL 查询性能

标签 sql sql-server-2017

此 SQL 查询需要 10 秒:

SELECT * FROM A a
JOIN B b on a.idB = b.idB
JOIN C c on b.idC = c.idC
JOIN D d on c.idD = d.idD
JOIN E e  ON((e.perimeterId = a.idA AND e.level = 3) 
          OR (e.perimeterId = b.idB AND e.level = 2) 
          OR (e.perimeterId = c.idC AND e.level = 1)
          OR (e.perimeterId = d.idD AND e.level = 0))

OR子句更改为CASE,查询需要3秒:

SELECT * FROM A a
JOIN B b on a.idB = b.idB
JOIN C c on b.idC = c.idC
JOIN D d on c.idD = d.idD
JOIN E e  ON (
               CASE e.level
                    when 3 then a.idA
                    when 2 then b.idB
                    when 1 then c.idC
                    when 0 then d.idD
               END
             ) = e.perimeterId 

如果我使用单独的 OR 子句执行查询,则查询将立即执行 没有我们的OR子句:

SELECT * FROM A a
JOIN B b on a.idB = b.idB
JOIN C c on b.idC = c.idC
JOIN D d on c.idD = d.idD
JOIN E e  ON (e.perimeterId = a.idX AND e.level = X) 

如何重写我的查询以立即执行或以高性能执行?

最佳答案

您只需要来自 e 的列,因此我将使用 exists 编写此内容:

SELECT e.*
FROM E e
WHERE EXISTS (SELECT 1
              FROM a
              WHERE e.perimeterId = a.idA AND e.level = 3
             ) OR
      EXISTS (SELECT 1
              FROM a JOIN
                   b
                   ON a.idB = b.idB
              WHERE e.perimeterId = b.idA AND e.level = 2
             ) OR
      EXISTS (SELECT 1
              FROM a JOIN
                   b
                   ON a.idB = b.idB JOIN
                   c
                   ON c.idC = b.idC
              WHERE e.perimeterId = c.idA AND e.level = 1
             ) OR
      EXISTS (SELECT 1
              FROM a JOIN
                   b
                   ON a.idB = b.idB JOIN
                   c
                   ON c.idC = b.idC JOIN
                   d
                   ON d.idD = c.idD
              WHERE e.perimeterId = d.idA AND e.level = 0
             );

我不是 100% 确定子查询中需要 JOIN,但我还是把它们留在了里面。

关于使用 OR 子句的 SQL 查询性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54595366/

相关文章:

sql - 如果语句包含 UNION、INTERSECT 或 EXCEPT 运算符(变体),则 ORDER BY 项必须出现在选择列表中

sql - 如何比较同一表(SQL Server)中的2行?

mysql - 查询获取MYSQL中列子集的总和

mysql - 提高 DATETIME 分组查询性能

sql-server-2017 - 语法错误(*EngineEdition!= 11)(Microsoft.SqlServer.Management.Sdk.Sfc)

json - 无法使用 OPENJSON 和 SQL Server 2017 解析具有动态键的对象数组

sql - 如何将 UNION 更改为 IN 子句?

mysql - SQL 使用 SUM : making two additions in the same statement?

sql - 在 CTE 查询中使用聚合函数

sparql - 在 Microsoft SQL Server 2017 图形数据库中查询可选关系的语法?