So sánh hiệu suất giữa việc sử dụng chức năng Tham gia và Cửa sổ để nhận giá trị độ trễ và độ trễ


10

Tôi có một bảng với hàng 20M, và mỗi hàng có 3 cột: time, id, và value. Đối với mỗi idtime, có một valuetrạng thái. Tôi muốn biết giá trị chì và độ trễ của một giá trị timecụ thể id.

Tôi đã sử dụng hai phương pháp để đạt được điều này. Một phương thức đang sử dụng phép nối và một phương thức khác là sử dụng các hàm cửa sổ dẫn / trễ với chỉ số được nhóm timevà bật id.

Tôi đã so sánh hiệu suất của hai phương thức này theo thời gian thực hiện. Phương thức nối mất 16,3 giây và phương thức chức năng cửa sổ mất 20 giây, không bao gồm thời gian để tạo chỉ mục. Điều này làm tôi ngạc nhiên vì chức năng cửa sổ dường như được nâng cao trong khi các phương thức nối là lực lượng vũ phu.

Đây là mã cho hai phương thức:

Tạo chỉ mục

create clustered index id_time
 on tab1 (id,time)

Tham gia phương pháp

select a1.id,a1.time
   a1.value as value, 
   b1.value as value_lag,
   c1.value as value_lead
into tab2
from tab1 a1
left join tab1 b1
on a1.id = b1.id
and a1.time-1= b1.time
left join tab1 c1
on a1.id = c1.id
and a1.time+1 = c1.time

Thống kê IO được tạo bằng SET STATISTICS TIME, IO ON:

Thống kê cho phương pháp tham gia

Đây là kế hoạch thực hiện cho phương thức nối

Phương pháp chức năng cửa sổ

select id, time, value, 
   lag(value,1) over(partition by id order by id,time) as value_lag,
   lead(value,1) over(partition by id order by id,time) as value_lead
into tab2
from tab1

(Chỉ đặt hàng bằng cách timetiết kiệm 0,5 giây.)

Dưới đây là kế hoạch thực hiện cho phương thức chức năng Window

Thống kê IO

[Thống kê cho phương thức chức năng Window 4]


Tôi đã kiểm tra dữ liệu sample_orig_month_1999và có vẻ như dữ liệu thô được sắp xếp tốt bởi idtime. Đây có phải là lý do của sự khác biệt hiệu suất?

Có vẻ như phương thức nối có số lần đọc logic hơn phương thức hàm cửa sổ, trong khi thời gian thực hiện cho cái trước thực sự ít hơn. Có phải bởi vì trước đây có một song song tốt hơn?

Tôi thích phương pháp chức năng cửa sổ vì mã ngắn gọn, có cách nào để tăng tốc cho vấn đề cụ thể này không?

Tôi đang sử dụng SQL Server 2016 trên Windows 10 64 bit.

Câu trả lời:


11

Hiệu suất chế độ hàng tương đối thấp của các chức năng LEADLAGcửa sổ so với tự tham gia là không có gì mới. Ví dụ, Michael Zilberstein đã viết về nó trên SQLblog.com vào năm 2012. Có khá nhiều chi phí trong các phần tử (lặp đi lặp lại), Dự án trình tự, Spool Window và các toán tử kế hoạch Stream Aggregate:

Phần kế hoạch

Trong SQL Server 2016, bạn có một tùy chọn mới, đó là cho phép xử lý chế độ hàng loạt cho các tổng hợp cửa sổ. Điều này đòi hỏi một số loại chỉ mục cột trên bảng, ngay cả khi nó trống. Sự hiện diện của một chỉ mục cột hiện đang được yêu cầu cho trình tối ưu hóa để xem xét các kế hoạch chế độ hàng loạt. Đặc biệt, nó cho phép toán tử chế độ hàng loạt Window Aggregate hiệu quả hơn nhiều.

Để kiểm tra điều này trong trường hợp của bạn, hãy tạo một chỉ mục cột không chứa dữ liệu trống:

 -- Empty CS index
CREATE NONCLUSTERED COLUMNSTORE INDEX dummy 
ON dbo.tab1 (id, [time], [value]) 
WHERE id < 0 AND id > 0;

Truy vấn:

SELECT
    T1.id,
    T1.[time],
    T1.[value],
    value_lag = 
        LAG(T1.[value]) OVER (
            PARTITION BY T1.id
            ORDER BY T1.[time]),
    value_lead =
        LEAD(T1.[value]) OVER (
            PARTITION BY T1.id
            ORDER BY T1.[time])
FROM dbo.tab1 AS T1;

Bây giờ nên đưa ra một kế hoạch thực hiện như:

Kế hoạch hàng loạt kế hoạch cửa hàng

... mà có thể thực hiện nhanh hơn nhiều.

Bạn có thể cần sử dụng một OPTION (MAXDOP 1)hoặc một gợi ý khác để có được hình dạng kế hoạch tương tự khi lưu trữ kết quả trong một bảng mới. Phiên bản song song của kế hoạch yêu cầu sắp xếp chế độ hàng loạt (hoặc có thể hai), có thể chậm hơn một chút. Nó khá phụ thuộc vào phần cứng của bạn.

Để biết thêm về toán tử Batch Mode Window Aggregate, hãy xem các bài viết sau của Itzik Ben-Gan:

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.