使用OR子句的SQL查询性能

时间:2019-02-08 15:15:04

标签: 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))

使用 CASE 更改 OR 子句,查询需要 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) 

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

3 个答案:

答案 0 :(得分:2)

您只需要<div class="container"> <div class="right">right</div> <div class="left">left</div> <div class="mid">midmidmidmidmidmidmidmid</div> </div>中的列,因此我将使用e来编写:

exists

我不是100%肯定子查询中需要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 ); ,但是无论如何我还是把它们留了下来。

答案 1 :(得分:0)

1)在a.idB,b.idB,b.idC,c.idC,c.idD,d.idD,e.perimeterId,e.level上创建索引

2) 试试这个

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) 
UNION ALL
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.idB AND e.level = 2) 
UNION ALL
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.idC AND e.level = 1) 
UNION ALL
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.idD AND e.level = 0) 

答案 2 :(得分:0)

大多数性能问题都是通过精心构建的索引解决的,在子句中,如果不必创建相应的过滤器列,请始终尝试使用主索引。