Tóm tắt câu hỏi
REBUILD
Chỉ mục cụm bị phân mảnh không hoạt động tốt, ngay cả sau khi chỉ mục. Nếu chỉ mục là REORGANIZED
hiệu suất tăng cho bảng / chỉ mục đã cho.
Tôi chỉ thấy hành vi bất thường này trên SQL Server 2016 trở lên, tôi đã thử nghiệm kịch bản này trên các phần cứng và phiên bản khác nhau (tất cả các máy cá nhân và tất cả đều có đĩa cứng xoay thông thường). Hãy cho tôi biết nếu cần thêm thông tin.
Đây có phải là một lỗi trong SQL Server 2016 trở đi không?
Tôi có thể cung cấp các chi tiết và phân tích đầy đủ với tập lệnh nếu có ai muốn, nhưng không cung cấp ngay bây giờ vì tập lệnh khá lớn và sẽ chiếm nhiều khoảng trống trong câu hỏi.
Vui lòng kiểm tra phiên bản ngắn hơn của tập lệnh mẫu được lấy từ liên kết được cung cấp bên dưới trong môi trường DEV của bạn nếu bạn có SQL Server 2016 trở lên.
KỊCH BẢN
-- SECTION 1
/*
Create a Test Folder in the machine and spefiy the drive in which you created
*/
USE MASTER
CREATE DATABASE RebuildTest
ON
( NAME = 'RebuildTest',
FILENAME = 'F:\TEST\RebuildTest_db.mdf',
SIZE = 200MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 50MB )
LOG ON
( NAME = 'RebuildTest_log',
FILENAME = 'F:\TEST\RebuildTest_db.ldf',
SIZE = 100MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10MB ) ;
GO
BEGIN TRAN
USE RebuildTest
select top 1000000
row_number () over ( order by (Select null)) n into Numbers from
sys.all_columns a cross join sys.all_columns
CREATE TABLE [DBO].FRAG3 (
Primarykey int NOT NULL ,
SomeData3 char(1000) NOT NULL )
ALTER TABLE DBO.FRAG3
ADD CONSTRAINT PK_FRAG3 PRIMARY KEY (Primarykey)
INSERT INTO [DBO].FRAG3
SELECT n , 'Some text..'
FROM Numbers
Where N/2 = N/2.0
Update DBO.FRAG3 SET Primarykey = Primarykey-500001
Where Primarykey>500001
COMMIT
-- SECTION 2
SELECT @@VERSION
/* BEGIN PART FRAG1.1 */
----- BEGIN CLEANBUFFER AND DATABASE AND MEASURE TIME
CHECKPOINT;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS TIME ON
Select Count_Big (*) From [DBO].[FRAG3] Where Primarykey >0 Option (MAxDop 1)
SET STATISTICS TIME OFF
----- END CLEANBUFFER AND DATABASE AND MEASURE TIME
-------------BEGIN PART FRAG1.2: REBUILD THE INDEX AND TEST AGAIN
--BEGIN Rebuild the Index
Alter Table [DBO].[FRAG3] REBUILD
--END Rebuild the Index
----- BEGIN CLEANBUFFER FROM DATABASE AND MEASURE TIME
CHECKPOINT;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS TIME ON
Select Count_Big (*) From [DBO].[FRAG3] Where Primarykey >0 Option (MAxDop 1)
SET STATISTICS TIME OFF
----- END CLEANBUFFER FROM DATABASE AND MEASURE TIME
--BEGIN REORGANIZE the Index
ALTER INDEX ALL ON [DBO].[FRAG3] REORGANIZE ;
--END REORGANIZE the Index
----- BEGIN CLEANBUFFER FROM DATABASE AND MEASURE TIME
CHECKPOINT;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS TIME ON
Select Count_Big (*) From [DBO].[FRAG3] Where Primarykey >0 Option (MAxDop 1)
SET STATISTICS TIME OFF
----- END CLEANBUFFER FROM DATABASE AND MEASURE TIME
-------------BEGIN PART FRAG1.4: REBUILD THE INDEX AND TEST AGAIN
--BEGIN Rebuild the Index
Alter Table [DBO].[FRAG3] REBUILD
--END Rebuild the Index
----- BEGIN CLEANBUFFER FROM DATABASE AND MEASURE TIME
CHECKPOINT;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS TIME ON
Select Count_Big (*) From [DBO].[FRAG3] Where Primarykey >0 Option (MAxDop 1)
SET STATISTICS TIME OFF
----- END CLEANBUFFER FROM DATABASE AND MEASURE TIME
-------------END PART FRAG1.4: REBUILD THE INDEX AND TEST AGAIN
Các kết quả
Kết quả kiểm tra đĩa Crystal
Chi tiết
Tôi đang thấy một hành vi bất thường của công cụ lưu trữ (có thể) trên SQL Server 2016 trở lên, tôi đã tạo một bảng phân mảnh cao cho mục đích demo (đọc phân mảnh) sau đó xây dựng lại nó.
Ngay cả sau khi xây dựng lại, hiệu suất chỉ mục không tăng như mong đợi. Để đảm bảo mẫu truy cập dữ liệu phải theo thứ tự chính không theo định hướng IAM (Quét phân bổ thứ tự), tôi đã sử dụng biến vị ngữ phạm vi.
Ban đầu, tôi nghĩ có lẽ SQL Server 2016 trở lên mạnh hơn đối với các bản quét lớn. Để kiểm tra điều đó, tôi đã điều chỉnh số trang và số hàng nhưng mẫu hiệu suất không thay đổi. Tôi đã thử nghiệm tất cả trên một hệ thống cá nhân để tôi có thể nói rằng không có hoạt động người dùng nào khác đang diễn ra.
Tôi cũng đã thử nghiệm hành vi này trên các phần cứng khác ( tất cả đều có đĩa cứng xoay truyền thống ). Các mẫu hiệu suất gần như giống nhau.
Tôi đã kiểm tra tất cả các số liệu thống kê chờ chỉ có vẻ bình thường PAGELATCH_IO
(sử dụng tập lệnh Paul Randal) ở đó. Tôi đã kiểm tra các trang dữ liệu bằng DMV sys.dm_db_database_page_allocations
thì cũng có vẻ ổn.
Nếu tôi sắp xếp lại bảng hoặc di chuyển tất cả dữ liệu sang một bảng mới với cùng một đĩa định nghĩa chỉ số thì hiệu suất IO sẽ tăng. Tôi đã kiểm tra điều này với perfmon và có vẻ như việc sắp xếp lại chỉ mục / bảng mới có thể thúc đẩy IO tuần tự và chỉ mục xây dựng lại vẫn sử dụng các lần đọc ngẫu nhiên mặc dù thực tế là cả hai đều có sự phân mảnh bên trong và bên ngoài.
Tôi đang đính kèm truy vấn đầy đủ với kết quả trên hệ thống của tôi mà tôi đã chụp. nếu các bạn có SQL Server 2016 trở lên hộp DEV, vui lòng kiểm tra điều này và chia sẻ kết quả của bạn.
CẢNH BÁO : Thử nghiệm này bao gồm một số lệnh không có giấy tờ và DROPCLEANBUFFERS
do đó không chạy ở máy chủ sản xuất.
Nếu đây thực sự là một lỗi tôi nghĩ tôi nên nộp nó.
Vì vậy, câu hỏi là: Nó thực sự là một lỗi hay tôi đang thiếu một cái gì đó;)
Liên kết (pastebin)
2 SP hỗ trợ CHẠY SAU KHI TẠO BẢNG