SQL IN子句导致扫描太多参数

时间:2013-07-10 21:04:15

标签: sql-server tsql

我无法理解我的查询结果:http://pastebin.com/sGVnq1jU

它按预期工作,但只要T2.CityId IN (...) CTE表达式的Clusters子句达到6个以上的值匹配,执行计划就会变为包括 一个昂贵的表扫描,查询变得非常慢。

关于这可能是什么的任何想法?

1 个答案:

答案 0 :(得分:1)

尝试避免使用IN子句来支持使用IN子句中的参数值构建的另一个CTE表的连接(下面)

此外,请确保map.ClusterDist.CityId列上有索引。

DECLARE @cityIds0 int, @cityIds1 int, @cityIds2 int, @cityIds3 int, @cityIds4 int, @cityIds5 int, @cityIds6 int, @cityIds7 int
 SELECT @cityIds0 = 0, @cityIds1 = 1, @cityIds2 = 2, @cityIds3 = 3, @cityIds4 = 4, @cityIds5 = 5, @cityIds6 = 6, @cityIds7 = 7

;WITH Cities AS
(
              SELECT @cityIds0 as [CityId]
    UNION ALL SELECT @cityIds1
    UNION ALL SELECT @cityIds2
    UNION ALL SELECT @cityIds3
    UNION ALL SELECT @cityIds4
    UNION ALL SELECT @cityIds5
    UNION ALL SELECT @cityIds6
    UNION ALL SELECT @cityIds7
), Clusters AS
(
    SELECT T1.*
          ,T2.CityId
      FROM map.Cluster T1
      JOIN map.ClusterDist T2 
        ON T2.Id    = T1.DistId
      JOIN Cities C 
        ON C.CityId = T2.CityId
       AND T2.Zoom  = @zoom
) -- etc...
SELECT * FROM Clusters

如果这对您的性能需求不起作用,可能是时候用一些旧的临时表来切换一些CTE表,您可以为这个特定的场景索引。