我正在使用SQL Server 2005,我注意到一些奇怪的事情,当我想在IN子句中使用子查询时过滤一些结果。例如,这是我目前的查询,并将其70秒运行一次,平均:使用IN(子查询)时性能损失较大。为什么?
select Phone, ZipCode, sum(Calls) as Calls, sum(Sales) as Sales
from Archive
where CustomerID = 20
and ReportDate = '2/3/2011'
and Phone in (
select Phone
from PlanDetails
where Phone is not null
and Length is not null
and PlannedImp > 0
and CustomerID = 20
and (StatusID <> 2 and StatusID <> 7)
and SubcategoryID = 88
)
group by Phone, ZipCode
但是,如果我把它们分解成2个独立的查询,他们采取低于1秒的每个运行。
select Phone
from PlanDetails
where Phone is not null
and Length is not null
and PlannedImp > 0
and CustomerID = 20
and (StatusID <> 2 and StatusID <> 7)
and SubcategoryID = 88
和
select Phone, ZipCode, sum(Calls) as Calls, sum(Sales) as Sales
from Archive
where CustomerID = 20
and ReportDate = '2/3/2011'
group by Phone, ZipCode
最后,如果我这样做,它返回相同的结果第一次查询,但在约2-3秒:
select Phone
into #tempTable
from PlanDetails
where Phone is not null
and Length is not null
and PlannedImp > 0
and CustomerID = 20
and (StatusID <> 2 and StatusID <> 7)
and SubcategoryID = 88
select Phone, ZipCode, sum(Calls) as Calls, sum(Sales) as Sales
from Archive
where CustomerID = 20
and ReportDate = '2/3/2011'
and Phone in (
select Phone
from #tempTable
)
group by Phone, ZipCode
在过去的几年几周来,我一直注意到,不仅这个查询很慢,而且在IN子句中使用(稍微复杂)子查询的任何查询都会破坏性能。这是什么原因?
可供这些查询使用的唯一索引是两个表的CustomerID上的非聚簇索引。我查看了慢速查询和快速查询的执行计划,发现存档表上的非聚簇索引查找占了迄今为止最高的成本百分比(80-90%)。但是,唯一的区别是慢速查询中的那一步CPU的成本为7.1,而快速的CPU的成本为1.7。
当这种事情发生(错误的查询计划)运行sp_updatestats有时可以解决问题。 – Magnus 2011-02-06 23:39:17