我有一个查询,运行时,结果是即时的。
但是,我将完全相同的查询粘贴到VIEW中,结果需要6秒才能回复。
例如,
SELECT ... FROM MyTables WHERE PersonID = x
跑得快。
但是创建一个视图:
SELECT ... FROM MyTables
然后调用视图:
SELECT * FROM MyView WHERE PersonID = x
它运行缓慢。
实际查询:
select ROW_NUMBER() over(partition by h.Id order by h.[SysStartTime]) as VersionNUmber,
h.Id,
fac.HIC,
... plus 18 other columns from the joined tables.
from [hist].[A_View] as h
inner join [dbo].[Facilities] as fac
on fac.Id = h.FacilityId
inner join ref.FormStatus as r_fs
on r_fs.Id = h.FormStatusId
inner join TableA as data
on data.Id = h.dataId
inner join Consultants as c
on c.Id = h.ConsultantId
inner join dbo.Specialties spec
on spec.Id = h.SpecialtyId
inner join dbo.Users modifieduser
on modifieduser.Id = h.ModifiedByUserId
left join ref.ARefTable as r_uc
on r_uc.Id = h.refId
cross apply [dbo].[getPersonUrn](h.PersonId, h.AnotherIdId) as PersonURN
(注意,我正在更改一些表名和列,因为我们处于相当机密的区域)
在执行视图时,我注意到97%的时间是排序(前N排序)。在查询中,这34%,但计划完全不同。
我怀疑参数嗅探,但不认为这是View的问题。
我实际上只是'修复'它,但不知道为什么。
我的选择中的第一列是ROW_NUMBER。
SELECT ROW_NUMBER() over(partition by h.Id order by h.[SysStartTime]) as` VersionNumber,
删除它,我得到即时结果。 不确定为什么,因为我订购和分区的列都已经在结果集中。
答案 0 :(得分:4)
1)此处ROW_NUMBER仅适用于过滤数据:
SELECT ROW_NUMBER(), ... FROM MyTables WHERE PersonID = x
首先按PersonID过滤,然后计算ROW_NUMBER
2)此处ROW_NUMBER适用于所有数据:
CREATE VIEW MyView as
select ROW_NUMBER(), ... FROM MyTables
SELECT * FROM MyView WHERE PersonID = x
并且仅在继续完整数据之后才应用PersonID过滤器
与
相同SELECT * FROM
(SELECT ROW_NUMBER(), ... FROM MyTables
) t
WHERE t.PersonID = x
查看示例:
GO
CREATE VIEW dbo.test_view
AS
SELECT ROW_NUMBER() OVER (ORDER BY NAME) rn, o.name, o.[object_id]
FROM sys.objects o
GO
SET SHOWPLAN_XML ON
GO
SELECT rn, o.name, o.[object_id] FROM dbo.test_view o
WHERE OBJECT_ID < 100
GO
SELECT ROW_NUMBER() OVER (ORDER BY NAME) rn, o.name, o.[object_id] FROM sys.objects o
WHERE OBJECT_ID < 100
GO
SET SHOWPLAN_XML OFF
GO
DROP VIEW dbo.test_view
GO
视图filter
操作就在最后。 所以计划实际上是不同的。
答案 1 :(得分:0)
我发现在视图中运行它时,它会用ROW_NUMBER()来计数每条记录,然后进行选择。当您在查询中运行它时,它只计算以ROW_NUMBER()返回的记录