|
我正在使用SQL Server 2005,当我想在IN子句中使用子查询时要过滤某些结果时,我注意到了一些奇怪的事情。例如,这是我当前的查询,平均运行70秒:1 _* h* n2 E# P& S1 Y) K5 t
select Phone, ZipCode, sum(Calls) as Calls, sum(Sales) as Sales
7 [2 A: {: E, {! `( S" afrom Archive 0 r! M/ d8 e% U8 A) q
where CustomerID = 20
; `4 L# S5 f3 n) G( r( H' [and ReportDate = '2/3/2011'
; i9 u4 \+ p& D1 e) dand Phone in (8 `0 S, j; {0 ~( R" G0 Q% {- ^
select Phone7 g4 p2 T- S' A- D+ l
from PlanDetails ) N; ?# d, r, l/ R$ z
where Phone is not null( o' T& e2 W5 B3 Y$ M4 ?
and Length is not null
1 W* K8 d+ q8 N3 y& q+ b and PlannedImp > 0
) y. Q# \$ ~6 K C) |0 o and CustomerID = 20' k6 B0 Y w3 R
and (StatusID 2 and StatusID 7)% W2 Z: z1 d# \) a
and SubcategoryID = 88/ Q$ L7 s! c" s# V1 n
): l+ S! {+ h) b7 F3 P Y
group by Phone, ZipCode
& E" L: ?. @( c6 p* [9 }; y* w% @但是,如果我将它们分解为2个独立的查询,则每个查询要花费不到1秒的时间。
$ Y4 s$ _7 h# Lselect Phone
# G9 i( a9 m* f6 ]3 ^( Wfrom PlanDetails 1 s7 g$ g+ n% A$ }; `3 B6 ?0 B
where Phone is not null
$ }% F! e; l" w9 B8 V# r0 tand Length is not null
* r1 d6 b. F$ X- R# M8 S( eand PlannedImp > 0
8 F2 h" j8 o/ W- N3 S5 i9 z1 Z' mand CustomerID = 203 h3 ?; s: P: X0 d+ I1 D
and (StatusID 2 and StatusID 7)
/ f& f' Y2 Y7 X, C# I$ Gand SubcategoryID = 882 s) @$ A% s2 i9 Z" P e
和" J1 |6 H c( Z, T2 t
select Phone, ZipCode, sum(Calls) as Calls, sum(Sales) as Sales
& m! ~) U* A2 s. W# {) Xfrom Archive
m K |: m& c2 T3 f$ dwhere CustomerID = 20+ V4 U# l j9 ~7 W
and ReportDate = '2/3/2011'
- b0 Y' @4 }% E9 S. S! v' N. lgroup by Phone, ZipCode# O6 ^0 X" d4 V) ~
最后,如果执行此操作,它将返回与第一个查询相同的结果,但大约需要2-3秒:
4 p# u/ Q* N# j, g- d* i+ |select Phone
) j- d/ x$ q9 Uinto #tempTable
+ I7 u. l: l* w* cfrom PlanDetails
6 k7 v7 G5 @6 I' G; d& @5 o4 [where Phone is not null
; A$ n8 c2 R7 \( d) Iand Length is not null
$ n" R$ u' J) J# \0 Hand PlannedImp > 05 c; [% K2 w9 Y5 p6 B) R" a: a
and CustomerID = 20
) ?7 \1 g' P* j* I0 A3 B$ \and (StatusID 2 and StatusID 7): H" f0 C& [9 w Q& r
and SubcategoryID = 88& h/ c7 v0 C* X" [2 @
select Phone, ZipCode, sum(Calls) as Calls, sum(Sales) as Sales
: H6 Q' [. p4 k* Y& D% G. Efrom Archive % }- J8 a: E/ j! F
where CustomerID = 20
! y; X6 L2 {( @. e0 kand ReportDate = '2/3/2011'4 H) m6 P, t9 W- A9 @
and Phone in (- A+ n9 U5 E. n( k/ D$ z
select Phone0 ~3 c' s! ^3 t+ F$ r. v o" Y
from #tempTable4 _# c# Y* ]4 Q6 n" [" U
)) E3 a+ z, B7 w% O$ l2 ]
group by Phone, ZipCode
7 Z5 _* N( f9 M" N5 {) E在过去的几周中,我一直注意到,不仅此查询的速度很慢,而且任何在IN子句中使用(有点复杂)子查询的查询都会破坏性能。是什么原因呢?& F" j) [* S* U" F! _2 r
这些查询中唯一可以使用的索引是两个表的CustomerID上的非聚集索引。我查看了慢查询和快速查询的执行计划,发现Archive表上的非聚集索引查找是迄今为止成本最高的百分比(80-90%)。但是,唯一的区别是慢查询中的这一步的CPU成本为7.1,而快查询中的这一步的CPU成本为1.7。
9 x, S* F c/ _# m+ m* H" ? $ U" V6 G! {, d$ R/ W* E
解决方案: |
|