Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 当涉及变量/函数时,简单的SQL Server查询将永远持续_Sql Server_Tsql - Fatal编程技术网

Sql server 当涉及变量/函数时,简单的SQL Server查询将永远持续

Sql server 当涉及变量/函数时,简单的SQL Server查询将永远持续,sql-server,tsql,Sql Server,Tsql,这是我挣扎了一段时间,但总是能找到解决的办法。 我在SQLServerDW中有一个事实表,它有大约3000万条记录,还有一个名为DateCreatedKey的整数字段,该字段上有一个非聚集索引。 然后我还有一个名为dbo.fn\u DateKeyFromDate的函数,它非常简单 declare @ret int = Year(@date) * 10000 + Month(@date) * 100 + Day(@date) return @ret 从下面的执行时间可以看出,在使用函数或变量时

这是我挣扎了一段时间,但总是能找到解决的办法。 我在SQLServerDW中有一个事实表,它有大约3000万条记录,还有一个名为DateCreatedKey的整数字段,该字段上有一个非聚集索引。 然后我还有一个名为
dbo.fn\u DateKeyFromDate
的函数,它非常简单

declare @ret int = Year(@date) * 10000 + Month(@date) * 100 + Day(@date) 
return @ret
从下面的执行时间可以看出,在使用函数或变量时,索引似乎无法正常工作。 不确定我是否遗漏了一些明显的东西

下面是这5段代码的执行时间:

  • A:0.034s:

    SELECT  * 
    INTO    #subs2
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= 20170814
    
    declare @fromdate int
    select  @fromdate = 20170814
    
    SELECT  * 
    INTO    #subs3
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    
    SELECT  * 
    INTO    #subs4
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    declare @fromdate int
    select  @fromdate = dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    SELECT  * 
    INTO    #subs 
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    
  • B:15.4s:

    SELECT  * 
    INTO    #subs2
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= 20170814
    
    declare @fromdate int
    select  @fromdate = 20170814
    
    SELECT  * 
    INTO    #subs3
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    
    SELECT  * 
    INTO    #subs4
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    declare @fromdate int
    select  @fromdate = dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    SELECT  * 
    INTO    #subs 
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    
  • C:134s:

    SELECT  * 
    INTO    #subs2
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= 20170814
    
    declare @fromdate int
    select  @fromdate = 20170814
    
    SELECT  * 
    INTO    #subs3
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    
    SELECT  * 
    INTO    #subs4
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    declare @fromdate int
    select  @fromdate = dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    SELECT  * 
    INTO    #subs 
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    
  • D:20s:

    SELECT  * 
    INTO    #subs2
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= 20170814
    
    declare @fromdate int
    select  @fromdate = 20170814
    
    SELECT  * 
    INTO    #subs3
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    
    SELECT  * 
    INTO    #subs4
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    declare @fromdate int
    select  @fromdate = dbo.fn_DateKeyFromDate(GETDATE()-1)
    
    SELECT  * 
    INTO    #subs 
    FROM    biWarehouse.dbo.factSubscriptions WITH (NOLOCK) 
    where   DateCreatedKey >= @fromdate
    

我想说,调用函数时不使用索引,但它应该与变量一起工作。我会比较执行计划以确定

如果您想使用该功能,请尝试以下操作(可能是您对130s示例的想法?)


我必须查看C的查询计划,但我假设它会将我指向该函数。但是A很快,因为您使用的是文本,SQL知道如何处理该值

由于使用局部变量,B和D的速度较慢。请看这里:

我可以想象,如果您创建了一个存储过程并传入值,那么您的执行时间将大大减少


或者您可以通过添加一个重新编译查询提示来测试它,这将允许优化器使用正确的统计信息。

您可以为一个运行快而慢的查询发布执行计划吗?您可以使用此链接发布计划:我相信您可能有一些数据类型转换。第四个查询与第三个查询相同。也许你可以用A、B、C等标记你的查询,这样我们就可以参考它们了。我知道,在某些情况下,函数不会停止字段的可搜索性,但我还是避免使用它们。您可能会从带有索引的持久化计算列中获得更好的性能。我相信当在where子句中使用
dbo.fn\u DateKeyFromDate(GETDATE()-1)
时,将对每一行求值。查询计划肯定会告诉您。谢谢,这些是指向执行计划的链接。我很好奇:如果您使用SCHEMABINDING声明函数
,结果会怎么样?(有关示例,请参阅。)您运行的是哪个版本的SQL Server?(
选择@@VERSION
)你说得对,很好。但是,该查询的执行时间仍然是20秒,大约是其应执行时间的600倍be@Niel请记住,在许多其他因素中,服务器缓存可能会改变您看到的结果的速度。如果要了解查询是否正在执行相同的操作,请检查它们的查询计划。