2

如何在编译期间使用 WHERE 子句中的 OR 将自身拆分为两个带有 UNION 的查询的查询?如果我手动重写它,使用 UNION 的查询比单个查询快 100 倍,因为它可以有效地在联合的每个查询中使用不同的索引。有什么办法可以让优化器使用这种方法?

我有一个看起来像这样的查询:

select columnlist
from table1
join table2 on joincond2
join table3 on joincond3
where conditions1 
    and ((@param1 is null and cond3a) or (cond3b))

其中 columnlist、joincond2、joincond3 和 conditions1 都是较长的表达式。更重要的是,OR 中只有一个条件永远为真。

我一开始以为我可以重写它来做联合,但后来我重复了 columnlist、joincond2、joincond3 和 conditions1,这是 20 行左右的 SQL,将来可能需要大量维护。有没有我可以提供的提示或更好的方法来编写 WHERE 子句?提前致谢。

4

2 回答 2

4

你可以分组

select columnlist
from table1
join table2 on joincond2
join table3 on joincond3

进入一个视图,然后使用union。

但是如果可以迁移到sql2005/8,可以使用公用表表达式。

with cte ( columnlist )
as (
    select columnlist
    from table1
    join table2 on joincond2
    join table3 on joincond3 )
select columnlist from cte where ...
union
select columnlist from cte where ...
于 2008-12-16T19:18:24.093 回答
0

尝试将 OPTION (RECOMPILE) 添加到查询中。如果它在存储过程中,那么也将 WITH RECOMPILE 添加到其中。可能是您第一次运行查询时 SQL Server 提出了一个计划并将其缓存,但第二次通过它仍然使用旧的(现在很差)查询计划。

您将受到轻微影响,因为每次使用查询时都需要重新编译,但与使用糟糕的计划相比,这将是微不足道的。

编辑:我读过在 SQL 2000 的存储过程中使用 WITH RECOMPILE 并不总是能正常工作。据说该错误已在 SQL 2005 中修复。不过,我个人从未遇到过该错误,所以我不知道具体的处理方式是什么。试试看吧。

于 2008-12-16T19:33:22.317 回答