使用变量和使用 T-SQL 查询之间存在巨大的性能差异常量

发布于 2024-09-30 11:37:38 字数 395 浏览 5 评论 0原文

所有,

当我在使用开始时设置的值的变量与实际使用该值作为查询中的常量之间的性能方面运行查询时,我看到一些非常奇怪的行为。

我所看到的是,它的

DECLARE @ID BIGINT
SET @ID = 5
SELECT * FROM tblEmployee WHERE ID = @ID

运行速度比我运行时快得多。

SELECT * FROM tblEmployee WHERE ID = 5

这显然是实际查询的一个简单版本,但是有人知道 SQL Server 2005 中的已知问题吗?它解析查询的方式可以解释这种行为。我最初的查询在两种方法之间从 13 秒缩短到 8 分钟。

谢谢, 阿什什

All,

I am seeing some really weird behavior when I run a query in terms of performance between using a variable that's value is set at the beginning to actually using the value as a constant in the query.

What I am seeing is that

DECLARE @ID BIGINT
SET @ID = 5
SELECT * FROM tblEmployee WHERE ID = @ID

runs much faster than when I run

SELECT * FROM tblEmployee WHERE ID = 5

This is obviously a simpler version of the actual query but does anyone know of known issues in SQL Server 2005 the way it parses queries that would explain this behavior. My original query goes from 13 seconds to 8 minutes between the two approaches.

Thanks,
Ashish

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

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

发布评论

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

评论(4

瑶笙 2024-10-07 11:37:38

你确定是这样吗?

通常,参数化查询会比较慢,因为 SQL Server 事先不知道参数是什么。常数可以立即优化。

不过,关于数据类型,这里需要注意的一件事......这是做什么的:

SELECT * FROM tblEmployee WHERE ID = CAST(5 as bigint)

另外,反转执行顺序。前几天我们看到了一些奇怪的事情,当我们改变订单时,计划也改变了。

另一种方式是,掩码 ID 可以消除“参数嗅探”对第一个查询的影响。和区别?

DECLARE @ID BIGINT
SET @ID = 5
DECLARE @MaskedID BIGINT
SET @MaskedID = @ID
SELECT * FROM tblEmployee WHERE ID = @MaskedID 

最后,为每个查询添加 OPTION (RECOMPILE)。这意味着该计划被丢弃并且不再被重新使用,因此它的编译方式有所不同。

Are you sure it's that way around?

Normally the parameterised query will be slower because SQL Server doesnp't know in advance what the parameter will be. A constant can be optimised right away.

One thing to note here about datatypes though.. what does this do:

SELECT * FROM tblEmployee WHERE ID = CAST(5 as bigint)

Also, reverse the execution order. We saw something odd the other day and the plans changed when we changed order.

Another way, mask ID to remove "parameter sniffing" affects on the first query. And difference?

DECLARE @ID BIGINT
SET @ID = 5
DECLARE @MaskedID BIGINT
SET @MaskedID = @ID
SELECT * FROM tblEmployee WHERE ID = @MaskedID 

Finally, add OPTION (RECOMPILE) to each query. It means the plan is discarded and not re-used so it compiles differently.

一腔孤↑勇 2024-10-07 11:37:38

您检查过每个查询计划吗?当我尝试分析性能问题时,这始终是我做的第一件事。

Have you checked the query plans for each? That's always the first thing I do when I'm trying to analyze a performance issue.

无声静候 2024-10-07 11:37:38

如果值被缓存,您可能会得出一个没有根据的结论:一种方法比另一种方法更快。总是有这种差异吗?

If values get cached, you could be drawing an unwarranted conclusion that one approach is faster than another. Is there always this difference?

呆° 2024-10-07 11:37:38

据我了解,这与缓存的查询计划有关。

当您运行 Select * from AWhere B = @C 时,无论 @C 的值如何,它都是一个查询计划。因此,如果您使用 @C 的不同值运行 10 次,则它是一个查询计划。

当你运行:

Select * from A Where B = 1 it creates a query plan
Select * from A Where B = 2 creates another
Select * from A Where B = 3 creates another

等等时。

这一切都会消耗内存。

谷歌查询计划缓存和文字,我相信你会找到详细的解释

From what I understand it's to do with cached query plans.

When you run Select * from A Where B = @C it's one query plan regardless of value of @C. so if you run 10x with different values for @C, it's a single query plan.

When you run:

Select * from A Where B = 1 it creates a query plan
Select * from A Where B = 2 creates another
Select * from A Where B = 3 creates another

etc.

All this does is eat up memory.

Google query plan caching and literals and I'm sure you turn up detail explanations

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