TSQL Tại sao Top nhanh hơn với một biến?


10

Buổi sáng tất cả,

Tôi đã làm việc trên một số sql phức tạp vừa phải để 'lấy' một số dữ liệu từ cơ sở dữ liệu sản phẩm của bên thứ ba, để hiển thị nó trong các ứng dụng nội bộ của chúng ta.

Tôi đã thêm vào một lựa chọn để có được bản ghi hàng đầu từ một bảng trong truy vấn con (nếu điều đó có ý nghĩa)

truy vấn mất gần 3 phút để trả về tập kết quả cuối cùng gồm 100 bản ghi bằng cách sử dụng

SELECT TOP 1 ...

Tôi đã xem trực tuyến các cải tiến cho những gì tôi đang cố gắng đạt được và được đề nghị rằng tôi thay đổi lựa chọn của mình để sử dụng một biến, như dưới đây

DECLARE @topCount INT
SET @topCount = 1

SELECT TOP (@topCount) ...

Điều này đã đưa cùng một truy vấn từ 3 phút xuống còn 1 giây, thật tuyệt!

Nhưng bất cứ ai có thể giải thích tại sao điều này là như vậy.

Câu trả lời:


14

Khi bạn thực hiện top 1trình tối ưu hóa truy vấn sẽ xây dựng một kế hoạch được xây dựng để tìm nạp 1 hàng nhanh nhất có thể.

Khi bạn sử dụng một biến cục bộ, giá trị của biến không xác định với trình tối ưu hóa và thay vào đó xây dựng một kế hoạch được tối ưu hóa để tìm nạp 100 hàng càng nhanh càng tốt.

Trong trường hợp của bạn, gói truy vấn được tạo với mục tiêu hàng là 100 là kế hoạch tốt hơn để sử dụng ngay cả khi bạn chỉ muốn một hàng.

Để xác minh, bạn có thể thử thêm option (recompile)vào truy vấn của mình bằng biến. Trong trường hợp đó, SQL Server sẽ sử dụng giá trị hiện tại @topCountlà mục tiêu hàng và vì đó là 1 nên bạn có được gói chậm.


Tôi hiểu sự khác biệt trong kế hoạch, nhưng điều làm tôi ngạc nhiên là việc tìm nạp 1 hàng có thể chậm hơn so với tìm nạp 100 hàng. Tôi nghĩ rằng nếu gói 100 hàng hoạt động tốt nhất, SQL Server sẽ sử dụng cùng một gói cho top 1.
Brandon

@Brandon nó không tìm nạp 100 hàng, chỉ xây dựng kế hoạch thực hiện với giả định rằng 100 hàng là điều mong muốn. Việc thực hiện chấm dứt khi tìm thấy 1 hàng.
Mikael Eriksson

Kiểm tra xem có gì khác với kế hoạch thực hiện trong những trường hợp này có lẽ sẽ giúp hiểu được vấn đề với top 1.
James Z
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.