Tôi có một cái bàn như thế này:
CREATE TABLE Updates
(
    UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    ObjectId INT NOT NULL
)Về cơ bản theo dõi cập nhật cho các đối tượng với một ID ngày càng tăng.
Người tiêu dùng của bảng này sẽ chọn một đoạn gồm 100 ID đối tượng riêng biệt, được sắp xếp theo thứ tự UpdateIdvà bắt đầu từ một cụ thể UpdateId. Về cơ bản, theo dõi nơi nó rời đi và sau đó truy vấn bất kỳ cập nhật nào.
Tôi thấy đây là một vấn đề tối ưu hóa thú vị vì tôi chỉ có thể tạo một kế hoạch truy vấn tối ưu tối đa bằng cách viết các truy vấn xảy ra để làm những gì tôi muốn do chỉ mục, nhưng không đảm bảo những gì tôi muốn:
SELECT DISTINCT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateIdTrong trường hợp @fromUpdateIdlà một tham số thủ tục lưu trữ.
Với một kế hoạch:
SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seekDo tìm kiếm trên UpdateIdchỉ mục đang được sử dụng, kết quả đã tốt đẹp và được sắp xếp từ ID cập nhật thấp nhất đến cao nhất như tôi muốn. Và điều này tạo ra một kế hoạch phân biệt dòng chảy , đó là những gì tôi muốn. Nhưng thứ tự rõ ràng là hành vi không được đảm bảo, vì vậy tôi không muốn sử dụng nó.
Thủ thuật này cũng dẫn đến cùng một kế hoạch truy vấn (mặc dù với TOP dư thừa):
WITH ids AS
(
    SELECT ObjectId
    FROM Updates
    WHERE UpdateId > @fromUpdateId
    ORDER BY UpdateId OFFSET 0 ROWS
)
SELECT DISTINCT TOP 100 ObjectId FROM idsMặc dù, tôi không chắc chắn (và nghi ngờ là không) nếu điều này thực sự đảm bảo cho việc đặt hàng.
Một truy vấn tôi hy vọng SQL Server sẽ đủ thông minh để đơn giản hóa điều này, nhưng cuối cùng nó lại tạo ra một kế hoạch truy vấn rất tệ:
SELECT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
GROUP BY ObjectId
ORDER BY MIN(UpdateId)Với một kế hoạch:
SELECT <- Top N Sort <- Hash Match aggregate (50,000+ rows touched) <- Index SeekTôi đang cố gắng tìm cách tạo ra một kế hoạch tối ưu với tìm kiếm chỉ mục UpdateIdvà một luồng khác biệt để loại bỏ các bản sao ObjectId. Có ý kiến gì không?
Dữ liệu mẫu nếu bạn muốn nó. Các đối tượng sẽ hiếm khi có nhiều hơn một bản cập nhật và hầu như không bao giờ có nhiều hơn một hàng trong một bộ 100 hàng, đó là lý do tại sao tôi sau một luồng khác biệt , trừ khi tôi không biết gì hơn? Tuy nhiên, không có gì đảm bảo rằng một đơn ObjectIdsẽ không có hơn 100 hàng trong bảng. Bảng có hơn 1.000.000 hàng và dự kiến sẽ tăng nhanh.
Giả sử người dùng này có một cách khác để tìm cái thích hợp tiếp theo @fromUpdateId. Không cần phải trả lại nó trong truy vấn này.





