Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.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 向where子句添加参数时的性能_Sql_Sql Server_Tsql_Sql Execution Plan_Sqlperformance - Fatal编程技术网

Sql 向where子句添加参数时的性能

Sql 向where子句添加参数时的性能,sql,sql-server,tsql,sql-execution-plan,sqlperformance,Sql,Sql Server,Tsql,Sql Execution Plan,Sqlperformance,我正在努力理解这种行为。我下面的陈述需要将近半个小时才能完成。但是,当我将参数@IsGazEnabled(在底部where子句的case语句中)替换为值1时,只需一秒钟 查看估计的执行计划,当使用该参数并且需要30分钟时,大部分成本(92%)都来自嵌套循环(左反半联接)。似乎也存在一些类似的情况。我只是在学习执行计划,我有点困惑。与不使用参数时生成的计划非常不同 那么,与没有参数相比,有参数如何对执行计划和性能产生如此大的影响呢 declare @IsGazEnabled tinyint; s

我正在努力理解这种行为。我下面的陈述需要将近半个小时才能完成。但是,当我将参数@IsGazEnabled(在底部where子句的case语句中)替换为值1时,只需一秒钟

查看估计的执行计划,当使用该参数并且需要30分钟时,大部分成本(92%)都来自嵌套循环(左反半联接)。似乎也存在一些类似的情况。我只是在学习执行计划,我有点困惑。与不使用参数时生成的计划非常不同

那么,与没有参数相比,有参数如何对执行计划和性能产生如此大的影响呢

declare @IsGazEnabled tinyint;

set @IsGazEnabled = 1;

select 'CT Ref: ' + accountreference + ' - Not synced due to missing property ref ' + t.PropertyReference
        from CTaxAccountTemp t
        where not exists (
            select *
            from ccaddress a
            left join w2addresscrossref x on x.UPRN = a.UPRN
                and x.appcode in (
                    select w2source
                    from GazSourceConfig
                    where GazSource in (
                        select GazSource
                        from GazSourceConfig
                        where W2Source = 'CTAX'
                    )
                    union all select 'URB'
                )
            where t.PropertyReference = case @IsGazEnabled when 1 then x.PropertyReference else a.PropertyReference end
        );

这可能是因为SQL Server(查询优化器)在创建初始执行计划时使用提供的参数值。如果某些表中的值分布不均匀,则创建的计划可能对参数的某些值非常有效,但对其他值却非常无效。这通常被称为参数嗅探。您可以使用查询提示(针对X进行优化)或在每次运行之前重新编译存储过程(使用重新编译)来解决此问题。在实施之前,您应该仔细阅读这些选项,因为它们都有副作用


有关更多详细信息,请参阅Brent Ozar网站上的几篇文章。

我认为您应该重新考虑这个问题。对于初学者,请尝试避免使用
NOT EXISTS()
,因为这通常效率很低(在这些情况下,我通常更喜欢
左连接
,以及相应的
,其中x为NULL
,x在右侧)

然而,造成问题的主要原因可能是基于案例的WHERE,因为这现在导致对每一行计算内部查询!。我认为最好将两组取消资格的条件都左键连接,但在连接条件中包含参数,然后检查两个左键连接的条件的右侧是否没有任何内容

以下是我认为可以改写的方式:

declare @IsGazEnabled tinyint;

set @IsGazEnabled = 1;

select 'CT Ref: ' + accountreference + ' - Not synced due to missing property ref ' + t.PropertyReference
    from CTaxAccountTemp t
    left join ccaddress a2 ON t.PropertyReference = a2.PropertyReference and @IsGazEnabled = 0
    left join 
        (
            ccaddress a
            join w2addresscrossref x on x.UPRN = a.UPRN
                and x.appcode in (       -- could make this a join for efficiency....
                    select w2source
                    from GazSourceConfig
                    where GazSource in (
                        select GazSource
                        from GazSourceConfig
                        where W2Source = 'CTAX'
                    )
                    union all select 'URB'
                )
        ) ON t.PropertyReference = x.PropertyReference AND  and @IsGazEnabled = 1
    WHERE 
          a2.PropertyReference IS NULL
          AND x.PropertyReference IS NULL      
    ;

当您不使用参数时,会使用什么类型的联接?您可以尝试在查询末尾添加选项(合并联接)或选项(哈希联接),看看是否有帮助。我还建议您重写查询以使用联接而不是嵌套(嵌套(嵌套子查询)))。这可能会自行解决问题。谢谢Dave。我只是在读参数嗅探。我想也许它只适用于程序。我将看一看这些文章。到目前为止,我对参数嗅探的阅读都提到它发生在存储过程中。这是一条直接在SSMS中运行的语句:/它也可以出现在临时语句中。如果查询sys.dm_exec_cached_计划,您将看到一个名为objtype的字段。这会告诉你这个计划是过程还是临时的。谢谢詹姆斯。我以前也使用过left join方法,但是我只是担心在使用join时由于数据错误而创建重复的行。我还认为在where子句中使用case语句会给它带来很大的冲击,但它似乎没有。只有当我添加参数时。因此,我很好奇为什么参数会对性能产生影响。但我一定会采纳你的建议。干杯。@ScubaManDan-case1=1可能会得到优化-因此,为什么只有当参数存在时,它才会导致命中。当右侧有重复数据时,左连接方法可以检查
不存在
(仔细想想),但作为
存在的替代方法当然不行。当我用“不存在”这个词的时候,我甚至都没想过。干杯。我已经解构了您提供给James的内容,并将参数放在联接条件中,这是一种享受。它的速度要快得多,所以我将把它标记为答案。我仍在努力理解原始查询花费如此长时间的根本原因。我只能相信,在我继续学习的过程中,我会明白这一点。谢谢