2016-02-26 36 views
7

我对以下表格有报告要求。我使用这些表创建了一个新数据库,并从实时数据库导入数据以用于报告目的。日期关联的优化不会更改计划

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

注:我使用SQL Server 2005

参考

  1. Optimizing Queries That Access Correlated datetime Columns
  2. The Query Optimizer: Date Correlation Optimisation

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' 

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] 

计划 enter image description here

-

+1

您是否尝试过丢弃当前的查询计划并重新运行,这样它会创建一个新的? –

+0

@JohnSpecko我也尝试过下面的命令 - 但没有改变。 'DBCC FREEPROCCACHE WITH NO_INFOMSGS;' – Lijo

+0

嗯。这很奇怪,我将不得不做一些额外的挖掘。 –

回答

4

根据文档: 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) 

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

CREATE NONCLUSTERED INDEX ON OrderLineItemContainers(CreatedOnDate) 
+1

请注意这一点“您不应在更新密集型数据库环境中启用DATE_CORRELATION_OPTIMIZATION”。如果是这种情况,您可能需要执行其他优化策略......比如将ContainersTest表中的候选行先拉到临时表中,然后再进行第二次连接。 –

+0

感谢您的回复。但即使在添加非聚集索引后,它也没有改变执行计划和时间 – Lijo