2016-12-14 154 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操作是在最後。 所以計劃實際上是不同的。

相關問題