日期关联的优化不会改变计划

LCJ*_*LCJ 7 sql-server optimization sql-server-2005

我有下表中的报告要求.我使用这些表创建了一个新数据库,并从实时数据库导入数据以进行报告.

报表参数是日期范围.我阅读了以下内容,发现DATE_CORRELATION_OPTIMIZATION可以通过使用seek而不是scan来更快地使查询工作.我做了必要的设置 - 仍然是查询使用相同的旧计划和相同的执行时间.需要进行哪些其他更改才能使查询使用日期关联?

注意:我使用的是SQL Server 2005

参考

  1. 优化访问相关日期时间列的查询
  2. 查询优化程序:日期关联优化

SQL

--Database change made for date correlation
ALTER DATABASE BISourcingTest
   SET DATE_CORRELATION_OPTIMIZATION ON;
GO

--Settings made
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET QUOTED_IDENTIFIER ON
SET NUMERIC_ROUNDABORT OFF
GO

--Test Setting
IF (  (sessionproperty('ANSI_NULLS') = 1) AND
      (sessionproperty('ANSI_PADDING') = 1) AND 
      (sessionproperty('ANSI_WARNINGS') = 1) AND 
      (sessionproperty('ARITHABORT') = 1) AND 
      (sessionproperty('CONCAT_NULL_YIELDS_NULL') = 1) AND 
      (sessionproperty('QUOTED_IDENTIFIER') = 1) AND 
      (sessionproperty('NUMERIC_ROUNDABORT') = 0)  
    )
   PRINT 'Everything is set'
ELSE
   PRINT 'Different Setting'

--Query
SELECT C.ContainerID, C.CreatedOnDate,OLIC.OrderID
FROM ContainersTest C
INNER JOIN OrderLineItemContainers OLIC
    ON OLIC.ContainerID = C.ContainerID
WHERE C.CreatedOnDate > '1/1/2015'
AND C.CreatedOnDate < '2/01/2015'
Run Code Online (Sandbox Code Playgroud)

TABLES

CREATE TABLE [dbo].[ContainersTest](
    [ContainerID] [varchar](20) NOT NULL,
    [Weight] [decimal](9, 2) NOT NULL DEFAULT ((0)),
    [CreatedOnDate] [datetime] NOT NULL DEFAULT (getdate()),
 CONSTRAINT [XPKContainersTest] PRIMARY KEY CLUSTERED 
(
    [CreatedOnDate] ASC,
    [ContainerID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[OrderLineItemContainers](
    [OrderID] [int] NOT NULL,
    [LineItemID] [int] NOT NULL,
    [ContainerID] [varchar](20) NOT NULL,
    [CreatedOnDate] [datetime] NOT NULL DEFAULT (getdate()),
 CONSTRAINT [PK_POLineItemContainers] PRIMARY KEY CLUSTERED 
(
    [OrderID] ASC,
    [LineItemID] ASC,
    [ContainerID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
 CONSTRAINT [IX_OrderLineItemContainers] UNIQUE NONCLUSTERED 
(
    [ContainerID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[OrderLineItemContainers]  WITH CHECK ADD  CONSTRAINT [FK_POLineItemContainers_Containers] FOREIGN KEY([ContainerID])
REFERENCES [dbo].[Containers] ([ContainerID])
GO
ALTER TABLE [dbo].[OrderLineItemContainers] CHECK CONSTRAINT [FK_POLineItemContainers_Containers]
Run Code Online (Sandbox Code Playgroud)

计划 在此输入图像描述

-

Bre*_*een 5

根据文档:https : //technet.microsoft.com/en-us/library/ms177416(v= sql.105) .aspx

如果维护相关统计信息的任何日期时间列不是聚集索引的第一个或唯一键,请考虑在其上创建聚集索引。这样做通常会在相关统计涵盖的查询类型上获得更好的性能。如果主键列上已经存在聚集索引,您可以修改表,使聚集索引和主键使用不同的列集。

由于您的 OrderLineItemContainers 表没有合适的索引来过滤日期,因此它真的无能为力。尝试在 OrderLineItemContainers.CreatedOnDate 上添加一个非聚集索引,看看它是否会切换计划。

最好将它聚集在一起,但还有其他注意事项……请注意,您可以将主键设为非聚集,并使用聚集作为新日期索引(如果这是占主导地位的查询)并且值得这样做。

所以这是最佳的:

CREATE TABLE [dbo].[OrderLineItemContainers](
      [OrderID] [int] NOT NULL,
      [LineItemID] [int] NOT NULL,
      [ContainerID] [varchar](20) NOT NULL,
      [CreatedOnDate] [datetime] NOT NULL DEFAULT (getdate()),
   CONSTRAINT [PK_POLineItemContainers] PRIMARY KEY NONCLUSTERED -- NONCLUSTERED PRIMARY KEY!!
        (
            [OrderID] ASC,
            [LineItemID] ASC,
            [ContainerID] ASC
        )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
         CONSTRAINT [IX_OrderLineItemContainers] UNIQUE NONCLUSTERED 
        (
            [ContainerID] ASC
        )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
        ) ON [PRIMARY]

CREATE CLUSTERED INDEX ON OrderLineItemContainers(CreatedOnDate)
Run Code Online (Sandbox Code Playgroud)

或者你可以尝试一个新的非聚集索引:

CREATE NONCLUSTERED INDEX ON OrderLineItemContainers(CreatedOnDate)
Run Code Online (Sandbox Code Playgroud)