Chỉ số nào sẽ được sử dụng trong kịch bản này?


11

Phiên bản tiêu chuẩn SQL Server 2014

Tôi cần tìm số chuyến bay đến và đi từ các thành phố cụ thể trong một số tháng nhất định. Ví dụ

select count(*) 
from flights 
where flightTo_AirportCode = 'aaaa' 
and flightFrom_Airportcode = 'bbbb' 
and flightdate < '2016-04-01' 
and flightdate > '2016-02-28' ;

Lược đồ bảng dưới đây.

Tôi đang cố gắng ước tính nếu mô hình chỉ mụcA hoặc mô hình chỉ mụcB (bên dưới) là thích hợp hơn (phải mất nhiều giờ để xây dựng chỉ mục và không gian đĩa chỉ cho phép một lần tồn tại, vì vậy tôi đang cố gắng tìm kiếm trước khi nhảy).

Từ kinh nghiệm của tôi, một trong hai chỉ số sẽ làm. Tôi có đúng không

  create index [modelA] on flights (flightTo_AirportCode, flightFrom_AirportCode, flightDate)

  create index [modelB] on flights (flightDate, flightTo_AirportCode, flightFrom_AirportCode)

(Hoặc, tốt hơn, có một chỉ số nhị phân hoặc cơ chế nâng cao mà tôi có thể sử dụng để tiếp cận điều này không?)

CREATE TABLE [dbo].[flights](
    [flightId] [uniqueidentifier] NOT NULL,
    [accountId] [uniqueidentifier] NULL,
    [flightDate] [datetime] NULL,
    [flightTo_AirportCode] [nvarchar](30) NULL,
    [flightFrom_AirportCode] [nvarchar](30) NULL,
    -- ... 45 more fields
    CONSTRAINT [PK_flight] PRIMARY KEY CLUSTERED 
(
    [flightId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 70) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

Câu trả lời:


18

Chỉ số A là tốt hơn cho truy vấn này. Khi tất cả các điều kiện trong WHEREkiểm tra đẳng thức ngoại trừ một điều kiện đang sử dụng một điều kiện phạm vi hoặc INtoán tử trên một cột, thì cột cuối cùng đó sẽ là cuối cùng trong chỉ mục, sau tất cả các cột có kiểm tra đẳng thức.

Điều này cho phép trình tối ưu hóa sử dụng một chỉ mục tìm đến hàng đầu tiên khớp với các điều kiện và sau đó duyệt qua chỉ mục cho đến khi tìm thấy một hàng không khớp với nó. Tất cả các hàng ở giữa là một trận đấu, quá.

Vì vậy, chỉ mục tốt nhất cho truy vấn này sẽ là (to, from, date)(mô hình A của bạn) hoặc (from, to, date).

Chỉ mục mô hình B có ngày đầu tiên vì vậy nó không phải là tốt nhất, mặc dù nó vẫn là một chỉ mục bao trùm cho truy vấn. Nếu điều này được sử dụng, kế hoạch truy vấn sẽ gần như giống nhau. Một chỉ mục tìm cách tìm hàng đầu tiên khớp với điều kiện phạm vi ( date > '2016-02-28') và sau đó duyệt qua chỉ mục cho đến khi tìm thấy một hàng không khớp với date < '2016-04-01'. Nhưng tất cả các hàng ở giữa không nhất thiết phải khớp với 2 điều kiện khác nên chúng sẽ phải được kiểm tra theo các điều kiện này và (có thể nhiều trong số chúng) bị từ chối.

Vì vậy, trong khi các kế hoạch sẽ tương tự nhau, kế hoạch mô hình A sẽ chỉ phải đi qua một phần của chỉ mục có tất cả các hàng cần thiết và chỉ có chúng, trong khi kế hoạch mô hình B sẽ đi qua một phần lớn hơn (có thể nhiều) mục lục.


  • Tốt nhất là sử dụng định dạng an toàn 100% cho ngày ( YYYYMMDD).

  • Và nếu bạn muốn ngày vào tháng 3, bạn nên sử dụng séc bao gồm độc quyền:

    AND flightdate >= '20160301' AND flightdate < '20160401' 

    Đảm bảo làm việc với các loại ngày và thời gian. Truy vấn hiện tại của bạn cũng sẽ bao gồm bất kỳ hàng nào có '2016-02-28'thời gian khác '00:00:00'(bạn có thể đảm bảo rằng không có bất kỳ hàng nào không?) Mà tôi cho rằng bạn không muốn. Phương pháp bao gồm cũng sẽ hoạt động trong những năm nhuận (nhắc nhở rằng năm 2016 là năm nhuận nên có ngày 29 tháng 2 cũng như truy vấn của bạn sẽ trở lại).

Đọc những bài viết trên blog của Aaron Bertrand:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.