Tôi có câu hỏi về chỉ mục SQL Server. Tôi không phải là một DBA và giả sử câu trả lời là rõ ràng cho những người bạn của bạn. Tôi đang sử dụng SQL Server 2008.Thứ tự chỉ mục SQL Server (trường ngày giờ)
Tôi có một bảng mà là tương tự như sau (nhưng có nhiều cột):
CREATE TABLE [dbo].[Results](
[ResultID] [int] IDENTITY(1,1) NOT NULL,
[TypeID] [int] NOT NULL,
[ItemID] [int] NOT NULL,
[QueryTime] [datetime] NOT NULL,
[ResultTypeID] [int] NOT NULL,
[QueryDay] AS (datepart(day,[querytime])) PERSISTED,
[QueryMonth] AS (datepart(month,[querytime])) PERSISTED,
[QueryYear] AS (datepart(year,[querytime])) PERSISTED,
CONSTRAINT [PK_Results] PRIMARY KEY CLUSTERED
(
[ResultID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
Các lĩnh vực cần lưu ý ở đây là ResultID, khóa chính, và QueryTime datetime mà tại đó kết quả được tạo ra.
Tôi cũng có chỉ số sau (giữa những người khác):
CREATE NONCLUSTERED INDEX [IDX_ResultDate] ON [dbo].[Results]
(
[QueryTime] ASC
)
INCLUDE ([ResultID],
[ItemID],
[TypeID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
Trong một cơ sở dữ liệu, nơi tôi có khoảng một triệu hàng trong bảng, chỉ số được sử dụng khi thực hiện một truy vấn như:
select top 1 * from results where querytime>'2009-05-01' order by ResultID asc
Trong một trường hợp khác của cùng một cơ sở dữ liệu, với 50 triệu hàng, SQL Server quyết định không sử dụng chỉ mục vì nó thực hiện quét chỉ mục cụm mà kết thúc là chậm khủng khiếp. (và tốc độ phụ thuộc vào ngày). Ngay cả khi tôi sử dụng gợi ý truy vấn để làm cho nó sử dụng IDX_ResultDate, nó vẫn còn một chút chậm và nó dành 94% thời gian phân loại bởi ResultID. Tôi thấy rằng bằng cách tạo một chỉ mục với cả ResultID và QueryTime như các cột được sắp xếp trong chỉ mục, tôi có thể tăng tốc truy vấn của mình.
do đó tôi tạo ra như sau:
CREATE NONCLUSTERED INDEX [IDX_ResultDate2] ON [dbo].[Results]
(
[QueryTime] ASC,
[ResultID] ASC
)
INCLUDE ([ItemID],
[TypeID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
Tôi cho rằng nó đầu tiên sẽ sử dụng sắp xếp theo QueryTime để tìm ra kết quả phù hợp, mà đã có thể được sắp xếp theo ResultID. Tuy nhiên, đây không phải là trường hợp như chỉ số này thay đổi không có gì trong hiệu suất so với hiện tại.
sau đó tôi đã thử các chỉ số sau:
CREATE NONCLUSTERED INDEX [IDX_ResultDate3] ON [dbo].[Results]
(
[ResultID] ASC,
[QueryTime] ASC
)
INCLUDE ([ItemID],
[TypeID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
một này tạo ra kết quả dự kiến. Nó xuất hiện để trở lại trong thời gian không đổi (một phần nhỏ của một giây).
Tuy nhiên, tôi không hiểu tại sao IDX_ResultDate3 hoạt động tốt trong khi IDX_ResultDate2 thì không.
Tôi giả định rằng tìm kiếm nhị phân trong danh sách được sắp xếp của QueryTime theo sau bằng cách nhìn vào kết quả đầu tiên trong danh sách con của ResultID là cách nhanh nhất để nhận kết quả. (Do đó thứ tự sắp xếp ban đầu của tôi).
Câu hỏi phụ: Tôi có nên tạo cột được lưu giữ với phần ngày của QueryTime và chỉ mục trên đó thay thế (tôi đã có ba cột được duy trì như bạn có thể thấy ở trên) không?
Giải thích rất tốt. Giờ thì tôi đã hiểu. Tôi sẽ xem liệu tôi có thể tái thiết kế ứng dụng để sử dụng sắp xếp QueryTime hay không. –