Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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 使用联合/或的TSQL存储过程性能问题_Sql Server_Performance_Stored Procedures_Indexing_Query Optimization - Fatal编程技术网

Sql server 使用联合/或的TSQL存储过程性能问题

Sql server 使用联合/或的TSQL存储过程性能问题,sql-server,performance,stored-procedures,indexing,query-optimization,Sql Server,Performance,Stored Procedures,Indexing,Query Optimization,我有一个静态表,我创建并构建索引,然后在该表上创建一个要运行的存储过程。我的问题很奇怪,我会尽力解释的 我运行相同的脚本来创建和执行194个数据库…其中绝大多数运行得非常快…但是在少数数据库上,它们运行得非常慢 CREATE PROC dbo.DC_GetPotentialDuplicates @ID int, @FirstName varchar(30), @LastName varchar(30), @PostalCode var

我有一个静态表,我创建并构建索引,然后在该表上创建一个要运行的存储过程。我的问题很奇怪,我会尽力解释的

我运行相同的脚本来创建和执行194个数据库…其中绝大多数运行得非常快…但是在少数数据库上,它们运行得非常慢

CREATE PROC dbo.DC_GetPotentialDuplicates
    @ID    int,   
    @FirstName  varchar(30),   
    @LastName   varchar(30),   
    @PostalCode varchar(10),
    @YearBorn   varchar(4)    
AS
SELECT  *
FROM    DC_DuplicateMatch
WHERE   (ID > @ID) AND 
        (
            (LastName   = @LastName   AND FirstName  = @FirstName)  OR
            (LastName   = @LastName   AND PostalCode = @PostalCode) OR
            (LastName   = @LastName   AND YearBorn   = @YearBorn)   OR
            (FirstName  = @FirstName  AND PostalCode = @PostalCode) OR  
            (FirstName  = @FirstName  AND YearBorn   = @YearBorn)   OR
            (PostalCode = @PostalCode AND YearBorn   = @YearBorn)   
        )
OPTION (RECOMPILE)        
GO
此过程在较大的表上始终运行得更快…较小的表“偶尔”运行得更慢。速度范围从4000条记录/秒“快”到70条记录/秒“慢”

问题是,如果我在某个点将空白填充记录添加到目标表中,而不进行任何其他更改,则速度将从70向上增加,接近4000标记。这就好像查询计划没有根据表中的记录数正确构建一样

为了避免添加空白记录以提高速度的麻烦,我重写了存储过程,使用联合而不是OR(生成相同的输出结果)

现在,这个存储过程在所有大型表上运行的速度都一样快……并且在大约1/2较小的有问题的表上提高了速度……但在其余的表上只给了我一点小小的改进。同样,如果我在较小的表上增加空白记录的记录数,性能也会提高

在运行了数据库引擎调谐器和性能监视器之后,无论是强制计划还是我尝试的任何优化,命中较小问题表的进程都会导致表扫描

有什么建议可以帮助我解决这个问题吗

~~~~~已更新~~~~
我已经大大缩小了问题的范围,这与一个没有缺失的索引有关

我刚刚发现,当我对联合进行重新排序时,列表中的最后一个联合无法使用索引,即使它在那里**

在上面的代码示例中,我确实交换了第一个和最后一个联合,现在存储的进程对LastName和firtname进行了表扫描,分析器抱怨索引丢失。
~~~~~~~~~
我已创建了一个新问题,该问题可以更好地定义问题,并包含位于此处的解决方案


您可以计数重复项,而不是检查每个排列:

SELECT  *
FROM    DC_DuplicateMatch
WHERE   (ID > @ID) AND 
        (
                CASE [LastName]   WHEN @LastName   THEN 1 ELSE 0 END +
                CASE [FirstName]  WHEN @FirstName  THEN 1 ELSE 0 END +
                CASE [PostalCode] WHEN @PostalCode THEN 1 ELSE 0 END +
                CASE [YearBorn]   WHEN @YearBorn   THEN 1 ELSE 0 END
        ) >= 2 

您可以计数重复项,而不是检查每个排列:

SELECT  *
FROM    DC_DuplicateMatch
WHERE   (ID > @ID) AND 
        (
                CASE [LastName]   WHEN @LastName   THEN 1 ELSE 0 END +
                CASE [FirstName]  WHEN @FirstName  THEN 1 ELSE 0 END +
                CASE [PostalCode] WHEN @PostalCode THEN 1 ELSE 0 END +
                CASE [YearBorn]   WHEN @YearBorn   THEN 1 ELSE 0 END
        ) >= 2 

您是否定期更新小表的统计数据?如果您不需要筛选重复的行,Als、o UNION ALL将运行得更快。表上有哪些索引?所有表都完全相同吗?将varchar隐式转换为nvarchar将导致索引扫描比seek更频繁。所有表都与我使用的相同.sql文件完全相同。我从头开始重新创建表,填充它们,然后创建索引。我还在末尾添加了updatestatistics调用,但没有效果。很可能是由于表中的数据不同,查询计划发生了更改。发布计划的两种变体。是否定期更新小表的统计信息?如果您不需要筛选重复的行,Als、o UNION ALL将运行得更快。表上有哪些索引?所有表都完全相同吗?将varchar隐式转换为nvarchar将导致索引扫描比seek更频繁。所有表都与我使用的相同.sql文件完全相同。我从头开始重新创建表,填充它们,然后创建索引。我还在末尾添加了updatestatistics调用,但没有效果。很可能是由于表中的数据不同,查询计划发生了更改。张贴计划的两个变体。