从代码中删除选项(重新编译)

时间:2016-10-24 09:30:56

标签: sql-server parameter-passing

我有这些疑问......

declare @month as int = 9
Select c1,c2
From table
Where datepart (m, InserDate) = @month

运行需要55分钟。

declare @month as int = 9
Select c1,c2
From table
Where datepart (m, InserDate) = @month
option (recompile)

需要9秒。

declare @month as int = 9
Select c1,c2
From table
Where datepart (m, InserDate) = 9

花7秒钟。

Select c1,c2
From table
Where datepart (m, InserDate) = 9

需要5秒

我的问题是,如何在不使用“选项(重新编译)”的情况下让第一个代码在几秒钟内运行

广告信息: 实际代码是:

DECLARE @Mon int = DATEPART(m, DATEADD(m, -1, getdate()))
DECLARE @Yr int = DATEPART(yyyy, DATEADD(m, -1, getdate()))

...

WHERE   
     DATEPART(m, cc.insertdate) = @Mon
     AND DATEPART(yyyy, cc.insertdate) = @Yr

InsertDate的值来自:2008-07-16 02:29:48.203至2016-10-24 07:06:58.337

而且,正如您所看到的,我只检索“上个月”数据...... 选项(重新编译)真的有必要吗?为什么sql不够智能?

1 个答案:

答案 0 :(得分:1)

假设您在insert_date字段上有一个合适的(覆盖)索引,您可以编写如下内容:

DECLARE @Mon int = DATEPART(m, DATEADD(m, -1, getdate()));
DECLARE @Yr int = DATEPART(yyyy, DATEADD(m, -1, getdate()));

SELECT
    c1,
    c2
FROM
    your_table
WHERE
    insert_date>=DATEFROMPARTS(@Yr,@Mon,1) AND
    insert_date<DATEADD(MONTH,1,DATEFROMPARTS(@Yr,@Mon,1));

您在问题中编写查询的方式不允许在insert_date字段上使用索引。这是因为您正在向其应用函数,然后才进行比较。