2011-02-18 70 views
2

我有以下兩個表:SQL Server 2005的視圖和子查詢的性能問題

- 約7000行

  • PerosnId - 9個字符
  • PersonType - 字符(的「F一個'/ 'C'/ 'M')

PersonStatuses - 約90K行(大致13行爲EA CH人行)

  • 標識 - 身份
  • PERSONID - 9字符
  • 的StatusCode - 整數
  • LASTUPDATEDATE - 日期時間

我使用一個視圖從返回最新行PersonStatuses realting一個獨特的人行:

LatestPersonStatuses

SELECT  PersonId, StatusCode 
FROM  PersonStatuses ps1 
WHERE  LastUpdateDate = (SELECT MAX(LastUpdateDate) 
            FROM PersonStatuses ps2 
            WHERE ps2.PersonId = ps1.PersonId) 

以下查詢:

SELECT DISTINCT Person.Id 
FROM Person 
WHERE Person.Id IN (SELECT PersonId 
       FROM LatestPersonStatuses 
       WHERE StatusCode = 12) AND 
Person.PersonType='F' 

Plan 1 http://i56.tinypic.com/n4tc9u.jpg

需要大約一分鐘,以藉此在,從而計時出,而執行以下操作:

SELECT DISTINCT Person.Id 
FROM Person 
WHERE Person.Id IN (SELECT PersonId 
        FROM LatestPersonStatuses 
        WHERE StatusCode = 12) 

執行幾乎立即。

Plan 2 http://i54.tinypic.com/5xjrbp.jpg

我想不通爲什麼在第一次查詢中添加WHERE子句:

Person.PersonType='F' 

造成這種差異。

可有人請直接我嗎?

+1

你有你的表的索引? – 2011-02-18 10:38:12

+0

對不起回答一個問題,但是......如果你忽略了`DISTINCT`,該怎麼辦?我明白`Id`對於`Person`必須是唯一的。 – 2011-02-18 10:45:46

回答

0

這是因爲查詢優化器已經決定,因爲您直接處理列persontype,所以在該列上使用索引可能會更快(如果有的話),或者如果不是,則直接表掃描+過濾。這是比較評估子查詢和做一個IN列表對比的感知/估算費用,不知道從子查詢列表中的度量/統計。

即使在看您的查詢,我將不得不幾乎猜測,這是更快地掃描和表列,而不是下降的子查詢,它涉及到的風景的擴張進行篩選。

你應該能夠改寫(爲2005+)的視圖

--VIEW: LatestPersonStatuses 
SELECT PersonId, StatusCode 
FROM (SELECT *, rownum=row_number() over (
        partition by personID order by LastUpdateDate desc) 
     from PersonStatuses p) X 
WHERE rownum = 1 

也許,這將有助於優化