Truy vấn SQL Server chậm khi được phân trang


14

Tôi đang thấy một số hành vi lạ với truy vấn T-SQL sau trong SQL Server 2012:

SELECT Id 
FROM dbo.Person 
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name

Chỉ thực hiện truy vấn này mang lại cho tôi khoảng 1.300 kết quả trong vòng chưa đầy hai giây (có chỉ mục toàn văn bản trên Name)

Tuy nhiên, khi tôi thay đổi truy vấn này:

SELECT Id 
FROM dbo.Person 
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY

Phải mất hơn 20 giây để cho tôi 10 kết quả.

Các truy vấn sau đây thậm chí còn tồi tệ hơn:

SELECT Id 
FROM ( 
    SELECT ROW_NUMBER() OVER (ORDER BY Name) AS RowNum, Id 
    FROM dbo.Person
    WHERE CONTAINS(Name, '"John" AND "Smith"') ) AS RowConstrainedResult 
WHERE RowNum >= 0 AND RowNum < 11 
ORDER BY RowNum

Phải mất hơn 1,5 phút để hoàn thành!

Có ý kiến ​​gì không?

Kế hoạch chậm

Chậm

Kế hoạch nhanh

Nhanh


Điều gì xảy ra nếu bạn thay đổi truy vấn thứ hai của bạn thành SELECT TOP 10 * .... ORDER BY Name?
Lamak

Trên cột nào chỉ mục IX_PersonSearch ... được thực hiện? Bạn đang nhận được tra cứu khóa vì bạn đang chọn * từ bảng và chỉ mục được sử dụng không chứa tất cả các cột đầu ra. Tôi nghĩ bạn chỉ nên chọn các cột bạn cần và sau đó đưa chúng vào chỉ mục không được nhóm như các cột được bao gồm, không phải các cột chỉ mục.
Marcel N.

Bạn có thể gửi cho bạn các chỉ mục trên bảng (tạo tập lệnh)?

3
ID luôn được bao gồm trong mọi chỉ mục không bao gồm. Đây là cách SQL Server có thể tìm kiếm khóa (bằng ID).
usr

1
Điều tôi quên đề cập: Khi tôi thực hiện cùng một truy vấn với THÍCH thay vì CONTAIN, thì cũng nhanh. (Được chiếu hay không)

Câu trả lời:


7

Vì bạn chỉ muốn TOP 10thứ tự theo tên, nó nghĩ rằng sẽ nhanh hơn để xử lý chỉ mục theo namethứ tự và xem liệu mỗi hàng có khớp với CONTAINS(Name, '"John" AND "Smith"') )vị ngữ không.

Có lẽ phải mất nhiều hàng hơn để tìm ra 10 trận đấu cần thiết sau đó nó mong đợi và vấn đề về số lượng thẻ này được kết hợp bởi số lần tra cứu chính.

Một cách nhanh chóng để ngăn chặn nó bằng cách sử dụng kế hoạch này sẽ là thay đổi ORDER BYthành ORDER BY Name + ''mặc dù sử dụng CONTAINSTABLEkết hợp với FORCE ORDERcũng sẽ hoạt động.


3

Điều này trông giống như sự đánh giá sai lầm cổ điển. Không chắc chắn những gì có thể được thực hiện về nó vì "trình điều khiển" của truy vấn là tìm kiếm toàn văn bản mà bạn không thể tăng số liệu thống kê.

Hãy thử viết lại where containsvị từ thành một inner join containstable( CONTAINSTABLE ) và áp dụng gợi ý thứ tự nối để buộc hình dạng của kế hoạch.

Đó không phải là một giải pháp hoàn hảo vì nó có vấn đề về bảo trì, nhưng tôi không thể thấy một cách khác.


Cảm ơn câu trả lời của bạn, tôi đã thử nó. Kết quả tương tự: Khi không sử dụng phân trang, truy vấn thực sự nhanh. Khi chiếu, nó đột nhiên trở nên rất chậm trở lại: /

Ok bạn có thể đăng kế hoạch như một hình ảnh và truy vấn của bạn? Tôi đoán rằng chúng ta chưa thành công để tạo ra hình dạng mong muốn.
usr

3

Tôi quản lý để giải quyết vấn đề:

Như tôi đã nói trong câu hỏi, có các chỉ số trên tất cả các cột + số liệu thống kê cho mỗi cột. (Vì các truy vấn THÍCH kế thừa) Tôi đã xóa tất cả các chỉ số và thống kê, thêm tìm kiếm toàn văn bản và voilà, truy vấn trở nên thực sự nhanh chóng.

Có vẻ như các chỉ số đã dẫn đến một Kế hoạch thực hiện khác.

Cám ơn tất cả các bạn vì đã giúp đỡ!


1
Tôi đoán xóa hoàn toàn chỉ mục là một cách để ngăn chặn nó được sử dụng, tôi đoán vậy!
Martin Smith
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.