在SQL Server 2000中强制或上的联合以进行优化

在SQL Server 2000中强制或上的联合以进行优化,sql,tsql,optimization,sql-server-2000,union,Sql,Tsql,Optimization,Sql Server 2000,Union,在编译过程中,如何获得使用WHERE子句中的OR将自身拆分为两个具有UNION的查询?如果我手动重写它,使用UNION的查询比单个查询快100倍,因为它可以在UNION的每个查询中有效地使用不同的索引。我有没有办法让优化器使用这种方法 我有一个类似以下内容的查询: select columnlist from table1 join table2 on joincond2 join table3 on joincond3 where conditions1 and ((@param1

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

我有一个类似以下内容的查询:

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子句?提前感谢。

您可以分组

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 ...
尝试向查询中添加选项(重新编译)。如果它在一个存储过程中,那么也可以通过重新编译来添加它。第一次运行查询时,SQL Server可能会提出一个计划并将其缓存,但第二次运行时,它仍然使用旧的(现在很糟糕的)查询计划

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


编辑:我读到在SQL 2000的存储过程中使用WITH RECOMPILE并不总是能正常工作。这个bug应该是在SQL2005中修复的。但是我个人从未遇到过这个bug,所以我不知道它的具体处理方法。试试看。

cond3a或cond3b是否与任何连接条件相关?这不完全是我所希望的,但它现在必须起作用。谢谢