2

我正在尝试优化 where 子句。它反复运行,我试图让查询更快地完成,但 or 语句显着减慢了它的速度。如果你们能帮上忙,那就太好了!

WHERE 
((Date1 >= @startdate
    AND Date1 <= @enddate
    AND @RunBy = 0) 
OR (date2 BETWEEN @startdate AND @enddate
    AND @RunBy = 1
    AND date2 BETWEEN @startdate AND @enddate)
OR (date3 BETWEEN @startdate AND @enddate
    AND @RunBy = 2)
OR (date4 >= @startdate
    AND date4 <= @enddate
    AND @RunBy = 3))

我试图放入一个案例或如果,但它只是不适合我。

4

5 回答 5

4

您的 where 子句可以重写为:

WHERE CASE @RunBy
  WHEN 0 THEN Date1
  WHEN 1 THEN Date2
  WHEN 2 THEN Date3
  WHEN 3 THEN Date4
END BETWEEN @startdate AND @enddate

这应该会加快速度,因为您正在最大限度地减少正在执行的比较次数。

它也更容易阅读和理解,这是好的编程的本质,而且看起来也很酷!

于 2013-04-16T20:59:10.640 回答
1

如果您期望不同的执行计划,则必须使用不同的查询文本。如果 date1、date2、date3 和 date4 上有索引,它们将不会与您当前的“多面”查询一起使用。根据您期望使用的执行计划分成 4 个查询。

IF @RunBy = 0
BEGIN
  SELECT...
  FROM ...
  WHERE date1 ...
END
ELSE IF @RunBy = 1
BEGIN
  SELECT ...
  FROM ...
  WHERE date2 ...
END
ELSE IF...
于 2013-04-16T21:03:12.357 回答
0

Something like this?

where case @RunBy
      when 1 then Date1
      when 2 then Date2
      when 3 then Date3
      when 4 then Date4
      else        null
      end between @startDate and @endDate

That won't necessarily improve your query plan, as I don't believe the optimizer will be able to use any indices on your Date1-4 columns, since case is a function: indices can't be applied to function expressions.

于 2013-04-16T21:04:33.253 回答
0

比较您将 OR“更改”为 UNION ALL 的查询的性能,例如:而不是

WHERE (A = @A)
OR (B = @B)

尝试

SELECT ...
FROM ...
WHERE A=@A

UNION ALL 

SELECT ...
FROM ...
WHERE B=@B

值得一试。

于 2013-04-16T20:35:58.580 回答
0

我看到 date2 部分中有一个条件重复。

OR (date2 BETWEEN @startdate AND @enddate
AND @RunBy = 1 AND date2 BETWEEN @startdate AND @enddate)

您可以坚持使用其中一种语法 - 使用 BETWEEN 或 >= 和 <= 组合。不要认为它会导致性能差异。

于 2013-04-16T20:56:04.940 回答