2016-02-26 15 views
7

Tôi có yêu cầu báo cáo từ các bảng sau. Tôi đã tạo một cơ sở dữ liệu mới với các bảng này và nhập dữ liệu từ cơ sở dữ liệu trực tiếp cho mục đích báo cáo.Tối ưu hóa cho Ngày Tương quan không thay đổi gói

Thông số báo cáo là phạm vi ngày. Tôi đọc những điều sau đây và thấy rằng DATE_CORRELATION_OPTIMIZATION có thể được sử dụng để làm cho truy vấn hoạt động nhanh hơn bằng cách sử dụng tìm kiếm thay vì quét. Tôi đã thực hiện các cài đặt bắt buộc - vẫn truy vấn đang sử dụng cùng một gói cũ và cùng một thời gian thực hiện. Những thay đổi bổ sung cần phải được thực hiện để làm cho truy vấn sử dụng mối tương quan ngày tháng?

Lưu ý: Tôi đang sử dụng SQL Server 2005

THAM KHẢO

  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' 

BẢNG

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] 

Kế hoạch enter image description here

-

+1

Các bạn đã thử bỏ kế hoạch truy vấn hiện tại và chạy lại để nó tạo ra một cái mới? –

+0

@JohnSpecko Tôi đã thử sau lệnh sau cũng - nhưng không thay đổi. 'DBCC FREEPROCCACHE WITH NO_INFOMSGS; ' – Lijo

+0

hmmm. Điều đó thật kỳ lạ, tôi sẽ phải đào thêm một số. –

Trả lời

4

Theo các tài liệu: https://technet.microsoft.com/en-us/library/ms177416(v=sql.105).aspx

Nếu bất kỳ một trong các cột ngày giờ mà các thống kê tương quan được duy trì không phải là khóa đầu tiên hoặc duy nhất của chỉ mục nhóm, hãy xem xét tạo chỉ mục nhóm trên đó. Việc làm này thường dẫn đến hiệu suất tốt hơn trên các loại truy vấn được bao gồm bởi các thống kê tương quan. Nếu chỉ mục nhóm đã tồn tại trên các cột khóa chính, bạn có thể sửa đổi bảng để chỉ mục nhóm và khóa chính sử dụng các tập hợp cột khác nhau.

Vì bảng OrderLineItemContainers của bạn không có chỉ mục phù hợp để lọc vào ngày, nó thực sự không thể làm gì cả. Hãy thử thêm một chỉ mục nonclustered trên OrderLineItemContainers.CreatedOnDate để xem nếu nó sẽ chuyển đổi kế hoạch. Nó sẽ là tốt hơn để có nó được nhóm lại, nhưng có những cân nhắc khác ... lưu ý bạn có thể làm cho khóa chính nonclustered, và sử dụng cụm cho chỉ số ngày mới này nếu đây là truy vấn thống trị và điều này làm cho nó đáng giá.

Vì vậy, đây là tối ưu:

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) 

HOẶC bạn chỉ có thể thử một chỉ số nonclustered mới:

CREATE NONCLUSTERED INDEX ON OrderLineItemContainers(CreatedOnDate) 
+1

Lưu ý điều này là "Bạn không nên bật DATE_CORRELATION_OPTIMIZATION trong môi trường cơ sở dữ liệu chuyên sâu cập nhật". Nếu đúng như vậy, bạn có thể muốn theo đuổi các chiến lược tối ưu hóa khác ... như kéo các hàng ứng cử viên từ bảng ContainersTest vào bảng tạm thời trước và sau đó thực hiện lần kết nối thứ hai. –

+0

Cảm ơn bạn đã trả lời. Nhưng ngay cả sau khi thêm chỉ số nonclustered, nó đã không thay đổi kế hoạch thực hiện và thời gian – Lijo

Các vấn đề liên quan