sql - 变量使查询性能变差
问题描述
我有这个查询,当我声明变量时性能会急剧下降:
DECLARE @StartDate DATETIME,
@EndDate DATETIME
SET @StartDate = '2018-08-13'
SET @EndDate = '2018-08-19'
SELECT *
FROM [DIME_WH].[dbo].[FactOrderLines2] FL (nolock)
WHERE DD_OrderDate >= @StartDate
AND DD_OrderDate <= @EndDate
这比这条 SQL 语句慢得多:
SELECT *
FROM [DIME_WH].[dbo].[FactOrderLines2] FL (nolock)
WHERE DD_OrderDate >= '2018-08-01'
AND DD_OrderDate <= '2018-08-17'
两个查询最终都将返回相同的结果。
解决方案
SELECT * FROM [DIME_WH].[dbo].[FactOrderLines2] FL (nolock)
WHERE DD_OrderDate >= '2018-08-01'
AND DD_OrderDate <= '2018-08-17'
当参数中使用常量时,则为此查询Optimiser
创建special plan
。因此,如果使用相同的值执行相同的查询,则重用计划,如果值更改,则创建另一个计划。
所以具有恒定值的参数很快。
SELECT *
FROM [DIME_WH].[dbo].[FactOrderLines2] FL (nolock)
WHERE DD_OrderDate >= @StartDate
AND DD_OrderDate <= @EndDate
在参数中使用变量时,优化器为传递的第一个参数值创建执行计划。
例如 @StartDate='2018-08-01'
,@EndDate='2018-08-07'
第一次通过值。然后优化器创建最佳执行计划。这个计划对于这个价值来说已经足够好了。下一次时间 @StartDate='2018-08-01'
和@EndDate='2018-08-31'
值通过,然后使用相同的先前计划,这可能不是此参数的最佳选择。
换句话说,对于第一个值是最优的相同计划对于另一个值是次优的。
所以查询可能会执行很差而且很慢。这被称为Parameter sniffing
.
有几种方法可以克服这个问题。
注意:在这个线程中,我们只关注为什么可变性能很慢,而其他因素保持不变。
推荐阅读
- ios - func didTapAt 坐标没有显示任何内容
- oracle - How to add additional where clause in existing view
- javascript - 每当我将更改推送到 GitHub 时,是否可以自动将我网站上的最后更新日期更改为当前日期?
- sharepoint - How to transfer all the data from one site to another in SharePoint?
- c++ - C++ :: 如何创建具有多重继承的类的构造函数?
- http - Custom HTTP headers in Razor Pages
- java - Unable to execute chromedriver on a Ubuntu instance (AWS) via Jenkins (The driver is not executable)?
- angular - 无法使用角度 2+ 中的复选框进行过滤
- wordpress - How can I access {{comment.author.roles}}?
- javascript - 如何在 MarkerClusterGroup 中设置每个集群的选项