SQL Query执行计划随where子句值而变化

时间:2017-05-03 19:38:52

标签: sql-server indexing

我编写了一个查询,根据日期范围查看大表(200M +行)中的数据点。查询非常简单,使用CTE然后从CTE汇总:

;WITH LMP
AS (
    SELECT CAISO.NODE AS NODE
        ,'CAISO' AS ISO
        ,[State]
        ,[County]
        ,(LMP) LMP
        ,(MCC) MCC
        ,(MCL) MCL
        ,(MCC_Perc_LMP) MCC_Perc_LMP
        ,(MCL_Perc_LMP) MCL_Perc_LMP
    FROM CAISO
    INNER JOIN CAISO_NODES ON CAISO.NODE = CAISO_NODES.NODE
    LEFT JOIN [Lookup:State] ON [Lookup:State].StateID = CAISO_NODES.StateID
    LEFT JOIN [Lookup:County] ON [Lookup:County].CountyID = CAISO_NODES.CountyID
    WHERE INTERVAL BETWEEN '2/18/2017'
            AND '3/3/2017'
    )
SELECT NODE
    ,ISO
    ,[State]
    ,[County]
    ,AVG(LMP) AvgLMP
    ,MAX(LMP) MaxLMP
    ,MIN(LMP) MinLMP
    ,AVG(MCC) AvgMCC
    ,MAX(MCC) MaxMCC
    ,MIN(MCC) MinMCC
    ,AVG(MCL) AvgMCL
    ,MAX(MCL) MaxMCL
    ,MIN(MCL) MinMCL
    ,AVG(MCC_Perc_LMP) Avg_MCC_Perc_LMP
    ,AVG(MCL_Perc_LMP) Avg_MCL_Perc_LMP
FROM LMP
GROUP BY NODE
    ,ISO
    ,[State]
    ,County

此表在INTERVAL列上编制索引

CREATE NONCLUSTERED INDEX [IX__CAISO__INTERVALSTARTTIME_GMT__NODE_PRICES] ON [dbo].[CAISO] ([INTERVAL] ASC) INCLUDE (
    [NODE]
    ,[LMP]
    ,[MCC]
    ,[MCE]
    ,[MCL]
    )
    WITH (
            PAD_INDEX = OFF
            ,STATISTICS_NORECOMPUTE = OFF
            ,SORT_IN_TEMPDB = OFF
            ,DROP_EXISTING = OFF
            ,ONLINE = OFF
            ,ALLOW_ROW_LOCKS = ON
            ,ALLOW_PAGE_LOCKS = ON
            ) ON [PRIMARY]
GO

现在这个查询对于我们的目的运行完全正常,执行大约需要6-10秒。但是,如果我将这些日期从“2017年2月18日”和“2017年3月3日”更改为“2017年4月18日”和“2017年5月3日”,则查询执行时间超过一分钟。

最令人费解的是执行计划的变化。

使用原始查询: Good Execution

更改日期: Bad Execution

我无法弄清楚为什么执行计划正在发生变化 - 更糟糕的是 - 当我们查询更新的数据时。我需要执行指数人口吗?我缺少一步?你可以在最右边看到两个查询都在命中我的索引。有小费吗?建议?

(另外,我不喜欢LEFT JOIN,但是即使它是NULL,也必须返回结果集的STATE和COUNTY)

(另外我也使用CTE而不仅仅是一个直接的SELECT-WHERE-GROUP查询,因为在将其他数据集合到其他应用程序之前,我还将其他数据合并到CTE中。我最关心的是这一个表的执行。)

0 个答案:

没有答案