SQL Server 2005视图&子查询性能问题

时间:2011-02-18 10:25:14

标签: performance sql-server-2005

我有以下两个表:

- 约7000行

  • PerosnId - 9个字符
  • PersonType - Char('F'/'C'/'M'之一)

PersonStatuses - 大约90K行(每个人行约13行)

  • Id - 身份
  • PersonId - 9个字符
  • StatusCode - 整数
  • LastUpdateDate - DateTime

我正在使用View将PersonStatuses中的最新行返回到一个唯一的Person行:

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 个答案:

答案 0 :(得分: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

也许这会对优化器有所帮助