在 SQL Server 2000 中强制对 OR 使用 UNION 进行优化

发布于 2024-07-10 14:50:21 字数 574 浏览 4 评论 0原文

如何获得一个在 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 和condition1 都是较长的表达式。 关键在于 OR 中只有一个条件为真。

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

How can I get a query which uses an OR in the WHERE clause to split itself into two queries with a UNION during compilation? If I manually rewrite it, the query using the UNION is 100x faster than the single query, because it can effectively use different indices in each query of the union. Is there any way I can make the optimizer use this approach?

I have a query that looks something like this:

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

Where columnlist, joincond2, joincond3, and conditions1 are all longer expressions. The kicker is that only one of the conditions in the OR is ever true.

I first thought I could just rewrite it to do the union, but then I am repeating columnlist, joincond2, joincond3, and conditions1, which is 20 or so lines of SQL that might need a lot of maintenance in the future. Is there a hint I can supply or some better way to write the WHERE clause? Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薆情海 2024-07-17 14:50:22

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

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

编辑:我读到在 SQL 2000 的存储过程中使用WITH RECOMPILE 并不总是能正常工作。 该错误据说已在 SQL 2005 中修复。不过我个人从未遇到过该错误,因此我不知道它的具体情况。 不过不妨尝试一下。

Try adding OPTION (RECOMPILE) to the query. If it's in a stored procedure then add WITH RECOMPILE to that as well. It may be that the first time that you run the query SQL Server comes up with a plan and caches it but then the second time through it's still using the old (and now poor) query plan.

You will take a minor hit because it will need to recompile every time you use the query, but it will be minuscule in comparison to the use of a poor plan.

EDIT: I've read that using WITH RECOMPILE in a stored procedure in SQL 2000 doesn't always work properly. The bug was supposedly fixed in SQL 2005. I've never encountered the bug personally though, so I don't know what the exact deal is with it. Give it a try though.

旧情勿念 2024-07-17 14:50:21

您可以分组

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 ...

You can group

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

into a view, and then use union.

but if you can migrate to sql2005/8,
you can use common table expression.

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 ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文