2016-12-14 462 views
2

我有一个查询,当运行时,结果是即时的。查询速度很快,但是当在VIEW中时,速度很慢 - 由于ROW_NUMBER

但是,我将完全相同的查询粘贴到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%,但计划完全不同。

我怀疑参数嗅探,但不认为这是视图的问题。

我实际上只是'固定'它,但不知道为什么。

我在我的第一列是第ROW_NUMBER。

SELECT ROW_NUMBER() over(partition by h.Id order by h.[SysStartTime]) as` VersionNumber, 

删除,我得到即时结果。 不确定为什么,因为我排序和分区的列都已经在结果集中。

+0

您是否检查过执行计划?您可以从工具栏中包含执行计划。在运行查询之后,您可以点击执行计划选项卡并查看正在进行的操作。 – KrishnaDhungana

+0

我做到了这一点,这就是我“97%的时间,它在一个排序(排名前N的排序)”。 – Craig

+1

您是使用top还是order by子句?你能发布实际的查询,表格脚本和执行计划吗?你是否在ssms中运行? – under

回答

3

1)这里ROW_NUMBER仅适用于过滤的数据:

SELECT ROW_NUMBER(), ... FROM MyTables WHERE PersonID = x 

起初它过滤由是PersonID,然后它计算ROW_NUMBER

2)这里ROW_NUMBER适用于所有的数据:

​​

并且仅在继续完整数据之后应用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操作是在最后。 所以计划实际上是不同的。

相关问题