Là toán tử spool háo hức hữu ích cho việc xóa này từ một cửa hàng cột cụm?


28

Tôi đang thử nghiệm xóa dữ liệu từ một chỉ mục của cửa hàng cột.

Tôi nhận thấy rằng có một toán tử spool háo hức lớn trong kế hoạch thực hiện:

nhập mô tả hình ảnh ở đây

Điều này hoàn thành với các đặc điểm sau:

  • 60 triệu hàng đã bị xóa
  • 1.9 GiB TempDB được sử dụng
  • Thời gian thực hiện 14 phút
  • Kế hoạch nối tiếp
  • 1 rebind trên ống chỉ
  • Chi phí ước tính để quét: 364.821

Nếu tôi lừa người ước tính đánh giá thấp, tôi sẽ có kế hoạch nhanh hơn để tránh sử dụng TempDB:

nhập mô tả hình ảnh ở đây

Chi phí quét dự kiến: 56.901

(Đây là một kế hoạch ước tính, nhưng những con số trong các bình luận là chính xác.)

Thật thú vị, ống chỉ biến mất một lần nữa nếu tôi tuôn ra các cửa hàng delta bằng cách chạy như sau:

ALTER INDEX IX_Clustered ON Fact.RecordedMetricsDetail REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);

Các spool dường như chỉ được giới thiệu khi có nhiều hơn một số ngưỡng của các trang trong các cửa hàng delta.

Để kiểm tra kích thước của các cửa hàng delta, tôi đang chạy truy vấn sau để kiểm tra các trang liên tiếp cho bảng:

SELECT  
  SUM([in_row_used_page_count]) AS in_row_used_pages,
  SUM(in_row_data_page_count) AS in_row_data_pages
FROM sys.[dm_db_partition_stats] as pstats
JOIN sys.partitions AS p
ON pstats.partition_id = p.partition_id
WHERE p.[object_id] = OBJECT_ID('Fact.RecordedMetricsDetail');

Có bất kỳ lợi ích hợp lý nào cho bộ lặp spool trong kế hoạch đầu tiên không? Tôi phải giả định rằng nó được dùng như một sự tăng cường hiệu suất và không phải để bảo vệ halloween vì sự hiện diện của nó không nhất quán.

Tôi đang thử nghiệm điều này trên CTP 3.1 2016, nhưng tôi thấy hành vi tương tự trên 2014 SP1 CU3.

Tôi đã đăng một tập lệnh tạo lược đồ và dữ liệu và hướng dẫn bạn cách trình bày vấn đề ở đây .

Câu hỏi chủ yếu là vì tò mò về hành vi của trình tối ưu hóa vào thời điểm này vì tôi có một cách giải quyết cho vấn đề đã đặt ra câu hỏi (một ống dẫn lớn chứa đầy TempDB). Bây giờ tôi đang xóa bằng cách sử dụng chuyển đổi phân vùng thay thế.


2
Nếu tôi thử OPTION (QUERYRULEOFF EnforceHPandAccCard)các ống chỉ biến mất. Tôi cho rằng HP có thể là "Bảo vệ Halloween". Tuy nhiên, sau đó cố gắng sử dụng kế hoạch đó với một USE PLANgợi ý không thành công (cũng như cố gắng sử dụng kế hoạch từ OPTIMIZE FOR cách giải quyết khác)
Martin Smith

Cảm ơn @MartinSmith. Bất cứ ý tưởng những gì AccCardsẽ được? Tăng dần cardinality cardinality có lẽ?
James L

1
@JamesLupolt Không, tôi không thể nghĩ ra điều gì đặc biệt thuyết phục với mình. Có lẽ Acc là Tích lũy hoặc Truy cập?
Martin Smith

Câu trả lời:


22

Có bất kỳ lợi ích hợp lý nào cho bộ lặp spool trong kế hoạch đầu tiên không?

Điều này phụ thuộc vào những gì bạn cho là "hợp lý", nhưng câu trả lời theo mô hình chi phí là có. Tất nhiên điều này là đúng, bởi vì trình tối ưu hóa luôn chọn gói rẻ nhất mà nó tìm thấy.

Câu hỏi thực sự là tại sao mô hình chi phí lại xem xét kế hoạch với ống chỉ rẻ hơn rất nhiều so với kế hoạch không có. Xem xét các gói ước tính được tạo cho một bảng mới (từ tập lệnh của bạn) trước khi bất kỳ hàng nào được thêm vào cửa hàng delta:

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE);

Chi phí ước tính cho kế hoạch này là 771.734 đơn vị khổng lồ :

Kế hoạch ban đầu

Chi phí gần như tất cả được liên kết với Xóa chỉ mục cụm, vì việc xóa được dự kiến ​​sẽ dẫn đến rất nhiều I / O ngẫu nhiên. Đây chỉ là logic chung áp dụng cho tất cả các sửa đổi dữ liệu. Ví dụ: một tập hợp sửa đổi không có thứ tự cho chỉ mục cây b được giả định dẫn đến kết quả là I / O ngẫu nhiên, với chi phí I / O cao liên quan.

Các gói thay đổi dữ liệu có thể có tính năng Sắp xếp để trình bày các hàng theo thứ tự sẽ thúc đẩy truy cập tuần tự, vì chính xác những lý do chi phí này. Tác động trở nên trầm trọng hơn trong trường hợp này vì bảng được phân vùng. Rất phân vùng, trên thực tế; kịch bản của bạn tạo ra 15.000 trong số họ. Các cập nhật ngẫu nhiên cho một bảng được phân vùng rất có chi phí đặc biệt cao do giá chuyển đổi phân vùng (hàng) giữa dòng cũng được cung cấp với chi phí cao.

Yếu tố chính cuối cùng cần xem xét là truy vấn cập nhật đơn giản ở trên (trong đó 'update' có nghĩa là bất kỳ hoạt động thay đổi dữ liệu nào, bao gồm xóa) đủ điều kiện để tối ưu hóa được gọi là "chia sẻ hàng", trong đó cùng một hàng nội bộ được sử dụng cho cả quét và cập nhật bảng. Kế hoạch thực hiện vẫn hiển thị hai toán tử riêng biệt, tuy nhiên, chỉ có một hàng được sử dụng.

Tôi đề cập đến điều này bởi vì có thể áp dụng tối ưu hóa này có nghĩa là trình tối ưu hóa có một đường dẫn mã đơn giản là không xem xét các lợi ích tiềm năng của việc sắp xếp rõ ràng để giảm chi phí cho I / O ngẫu nhiên. Trường hợp bảng là cây b, điều này có ý nghĩa, bởi vì cấu trúc vốn đã được sắp xếp, do đó việc chia sẻ các hàng cung cấp tất cả các lợi ích tiềm năng một cách tự động.

Hậu quả quan trọng là logic chi phí cho toán tử cập nhật không xem xét lợi ích đặt hàng này (thúc đẩy I / O tuần tự hoặc tối ưu hóa khác) trong đó đối tượng cơ bản là lưu trữ cột. Điều này là do sửa đổi cửa hàng cột không được thực hiện tại chỗ; họ sử dụng một cửa hàng delta. Do đó, mô hình chi phí phản ánh sự khác biệt giữa các cập nhật hàng chia sẻ trên các cây b so với các cột.

Tuy nhiên, trong trường hợp đặc biệt của một cửa hàng cột được phân vùng (rất!), Vẫn có thể có lợi cho việc đặt hàng được bảo toàn, trong đó thực hiện tất cả các cập nhật cho một phân vùng trước khi chuyển sang quan điểm I / O tiếp theo vẫn có thể có lợi từ quan điểm I / O .

Logic chi phí tiêu chuẩn được sử dụng lại cho các cửa hàng cột ở đây, vì vậy một kế hoạch duy trì thứ tự phân vùng (mặc dù không đặt hàng trong mỗi phân vùng) có chi phí thấp hơn. Chúng ta có thể thấy điều này trên truy vấn thử nghiệm bằng cách sử dụng cờ theo dõi không có giấy tờ 2332 để yêu cầu đầu vào được sắp xếp cho toán tử cập nhật. Điều này đặt thuộc DMLRequestSorttính thành đúng khi cập nhật và buộc trình tối ưu hóa tạo ra một kế hoạch cung cấp tất cả các hàng cho một phân vùng trước khi chuyển sang phân vùng tiếp theo:

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332);

Chi phí ước tính cho kế hoạch này thấp hơn rất nhiều, ở mức 52,5174 đơn vị:

DMLRequestSort = kế hoạch thực sự

Việc giảm chi phí này là do chi phí I / O ước tính thấp hơn tại bản cập nhật. Spool được giới thiệu thực hiện không có chức năng hữu ích, ngoại trừ nó có thể đảm bảo đầu ra theo thứ tự phân vùng, theo yêu cầu của bản cập nhật với DMLRequestSort = true(quét nối tiếp của chỉ mục lưu trữ cột không thể cung cấp bảo đảm này). Bản thân chi phí của bộ đệm được coi là tương đối thấp, đặc biệt là so với việc giảm (có thể không thực tế) về chi phí khi cập nhật.

Quyết định về việc có yêu cầu đầu vào có trật tự cho toán tử cập nhật hay không được đưa ra từ rất sớm trong tối ưu hóa truy vấn. Các heuristic được sử dụng trong quyết định này chưa bao giờ được ghi nhận, nhưng có thể được xác định thông qua thử và sai. Dường như quy mô của bất kỳ cửa hàng delta nào là đầu vào cho quyết định này. Sau khi thực hiện, sự lựa chọn là vĩnh viễn cho việc biên dịch truy vấn. Không có USE PLANgợi ý nào sẽ thành công: mục tiêu của kế hoạch hoặc đã ra lệnh nhập vào bản cập nhật, hoặc không.

Có một cách khác để có được một kế hoạch chi phí thấp cho truy vấn này mà không giới hạn một cách giả tạo ước tính cardinality. Một ước tính đủ thấp để tránh Spool có thể sẽ dẫn đến DMLRequestSort là sai, dẫn đến chi phí kế hoạch ước tính rất cao do I / O ngẫu nhiên dự kiến. Một cách khác là sử dụng cờ theo dõi 8649 (kế hoạch song song) kết hợp với 2332 (DMLRequestSort = true):

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332, QUERYTRACEON 8649);

Điều này dẫn đến một kế hoạch sử dụng quét song song theo chế độ hàng loạt phân vùng và trao đổi luồng (hợp nhất) bảo toàn thứ tự: hợp nhất:

Đã ra lệnh xóa

Tùy thuộc vào hiệu quả thời gian chạy của thứ tự phân vùng trên phần cứng của bạn, điều này có thể hoạt động tốt nhất trong ba. Điều đó nói rằng, sửa đổi lớn không phải là một ý tưởng tuyệt vời trên cửa hàng cột, vì vậy ý ​​tưởng chuyển đổi phân vùng gần như chắc chắn tốt hơn. Nếu bạn có thể đối phó với thời gian biên dịch dài và các lựa chọn kế hoạch kỳ quặc thường thấy với các đối tượng được phân vùng - đặc biệt là khi số lượng phân vùng lớn.

Kết hợp nhiều tính năng, tương đối mới, đặc biệt là gần giới hạn của chúng, là một cách tuyệt vời để có được các kế hoạch thực hiện kém. Độ sâu của hỗ trợ tối ưu hóa có xu hướng cải thiện theo thời gian, nhưng sử dụng 15.000 phân vùng của cửa hàng cột có thể sẽ luôn có nghĩa là bạn sống trong thời gian thú vị.

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.