sql-server – 为什么T-SQL变量比基于GETDATE()函数的比较慢?
发布时间:2020-12-12 06:38:01 所属栏目:MsSql教程 来源:网络整理
导读:我有一个T-SQL语句,我正在对一个有很多行的表运行.我看到一些奇怪的行为.将DateTime列与预先计算的值进行比较比将每行与基于GETDATE()函数的计算进行比较要慢. 以下SQL需要8秒: SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDGODECLARE @TimeZoneOffset
我有一个T-SQL语句,我正在对一个有很多行的表运行.我看到一些奇怪的行为.将DateTime列与预先计算的值进行比较比将每行与基于GETDATE()函数的计算进行比较要慢.
以下SQL需要8秒: SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED GO DECLARE @TimeZoneOffset int = -(DATEPART("HH",GETUTCDATE() - GETDATE())) DECLARE @LowerTime DATETIME = DATEADD("HH",ABS(@TimeZoneOffset),CONVERT(VARCHAR,GETDATE(),101) + ' 17:00:00') SELECT TOP 200 Id,EventDate,Message FROM Events WITH (NOLOCK) WHERE EventDate > @LowerTime GO 这个替代奇怪地立刻返回: SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED GO SELECT TOP 200 Id,Message FROM Events WITH (NOLOCK) WHERE EventDate > GETDATE()-1 GO 为什么第二个查询要快得多? 编辑:我更新了SQL以准确反映我正在使用的其他设置 解决方法经过大量的阅读和研究,我发现这里的问题是参数嗅探. Sql Server尝试根据where子句确定如何最好地使用索引,但在这种情况下,它并没有做得很好.请参阅以下示例: 慢版: declare @dNow DateTime Select @dNow=GetDate() Select * From response_master_Incident rmi Where rmi.response_date between DateAdd(hh,-2,@dNow) AND @dNow 快速版: Select * From response_master_Incident rmi Where rmi.response_date between DateAdd(hh,GetDate()) AND GetDate() “快速”版本的运行速度比慢速版本快10倍. Response_Date字段已编制索引,并且是DateTime类型. 解决方案是告诉Sql Server如何最好地优化查询.修改示例如下以包含OPTIMIZE选项导致它使用与“快速版本”相同的执行计划.这里的OPTMIZE选项明确告诉sql server将本地@dNow变量视为日期(好像将它声明为DateTime不够:s) 这样做时要小心,因为在更复杂的WHERE子句中,最终可能会使查询的性能比Sql Server自身的优化更差. declare @dNow DateTime SET @dNow=GetDate() Select ID,response_date,call_back_phone from response_master_Incident rmi where rmi.response_date between DateAdd(hh,@dNow) AND @dNow -- The optimizer does not know too much about the variable so assumes to should perform a clusterd index scann (on the clustered index ID) - this is slow -- This hint tells the optimzer that the variable is indeed a datetime in this format (why it does not know that already who knows) OPTION(OPTIMIZE FOR (@dNow = '99991231')); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- SqlServer判断数据库、表、存储过程、函数是否存在
- SQLServer 2008打开问题——连接不到local
- 如何区分SQL数据库中的主键与外键
- SQLSERVER2008 数据库可疑的解决方法
- SQL * Plus不执行SQL Developer所执行的SQL脚本
- ODI连接sqlservcer2008
- 揭秘SQL Server 2014有哪些新特性(3)-可更新列存储聚集索引
- SQL Server select into 和 insert into select 两种表复制
- 将行合并到一个CSV文件(a.k.a SQL Server的GROUP_CONCAT)
- ResultSet may only be accessed in a forward direction