sql – 为什么如果在WHERE子句中一个常量被一个参数替换(具有相
发布时间:2020-12-12 08:49:14 所属栏目:MsSql教程 来源:网络整理
导读:我有一个递归查询,如果WHERE子句包含一个常量,执行速度非常快,但如果用具有相同值的参数替换常量,则会变得非常慢. 查询#1 – 具有常量 ;WITH Hierarchy (Id,ParentId,Data,Depth)AS( SELECT Id,NULL AS Data,0 AS Depth FROM Test UNION ALL SELECT h.Id,t.Pa
我有一个递归查询,如果WHERE子句包含一个常量,执行速度非常快,但如果用具有相同值的参数替换常量,则会变得非常慢.
查询#1 – 具有常量 ;WITH Hierarchy (Id,ParentId,Data,Depth) AS ( SELECT Id,NULL AS Data,0 AS Depth FROM Test UNION ALL SELECT h.Id,t.ParentId,COALESCE(h.Data,t.Data),Depth + 1 AS Depth FROM Hierarchy h INNER JOIN Test t ON t.Id = h.ParentId ) SELECT * FROM Hierarchy WHERE Id = 69 查询#2 – 带参数 DECLARE @Id INT SELECT @Id = 69 ;WITH Hierarchy (Id,Depth + 1 AS Depth FROM Hierarchy h INNER JOIN Test t ON t.Id = h.ParentId ) SELECT * FROM Hierarchy WHERE Id = @Id 如果一个表为50,000行的查询,常量运行10毫秒,参数的运行速度为30秒(低于3,000倍). 将最后一个WHERE子句移动到递归的锚定定位不是一个选择,因为我想使用该查询创建一个视图(没有最后一个WHERE).从视图中选择将有WHERE子句(WHERE Id = @Id) – 我需要这个因为Entity Framework,但这是另一个故事. 有人建议强制使用查询#2(使用参数)的方式使用与查询1相同的查询计划(带常量)吗? 我已经尝试玩索引,但没有帮助. 如果有人想我可以发布表定义和一些样本数据. 谢谢你的帮助提前! 执行计划 – 查询#1 – 具有常量 执行计划 – 查询#2 – 带参数 解决方法正如Martin在问题的意见中建议的那样,问题是SQL Server没有正确地从WHERE子句中正确地推下谓词 – 请参阅他的评论中的链接.最后我创建一个用户定义的表值函数,并用CROSS APPLY操作符来创建视图. 让我们看看解决方案本身. 用户定义的表值函数 CREATE FUNCTION [dbo].[TestFunction] (@Id INT) RETURNS TABLE AS RETURN ( WITH Hierarchy (Id,Depth) AS( SELECT Id,0 AS Depth FROM Test Where Id = @Id UNION ALL SELECT h.Id,Depth + 1 AS Depth FROM Hierarchy h INNER JOIN Test t ON t.Id = h.ParentId ) SELECT * FROM Hierarchy ) 视图 CREATE VIEW [dbo].[TestView] AS SELECT t.Id,f.Data,f.Depth FROM Test AS t CROSS APPLY TestFunction(Id) as f 用常量进行查询 SELECT * FROM TestView WHERE Id = 69 查询参数 DECLARE @Id INT SELECT @Id = 69 SELECT * FROM TestView WHERE Id = @Id 与parmator的查询执行基本上与使用常量的查询一样快. 谢谢马丁和其他人! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |