2015-01-27 19 views
7

Tôi đã truy vấn sau đó mất < 1s khi ORDER BY b.Price được sử dụng, và hơn 10s khi ORDER BY b.Price DESC được sử dụngORDER BY cột được lập chỉ mục vẫn còn chậm

select * from 
(
    select 
     /* When changed to ORDER BY b.Price DESC it's 10x slower! */ 
     (row_number() over (ORDER BY b.Price)) as RowNumber, 
     b.*  
    from 
     Books b (nolock) 
     inner join BookPublishRegions p (nolock) 
      on b.BookKey = bp.BookKey 
    where  
     contains(p.PublishRegionName, 'France') 
) as t1 
where t1.RowNumber between 100 and 110 

Bất kỳ suy nghĩ về lý do tại sao?

Tôi có cả chỉ số tăng dần và giảm dần trên b.Price. Tôi không thực sự chắc chắn những gì khác tôi có thể làm ở đây ...

Để tham khảo, tôi bao gồm CREATE kịch bản cho cả hai chỉ số dưới đây:

CREATE NONCLUSTERED INDEX [IX_Books_PriceDesc] ON [dbo].[Books] 
(
    [Price] DESC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 


CREATE NONCLUSTERED INDEX [IX_Books_Price] ON [dbo].[Books] 
(
    [Price] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
+0

Hiển thị cho chúng tôi các chỉ mục –

+0

Bạn có thể có chỉ mục trên Price asc thay đổi nó thành DESC https://technet.microsoft.com/en-us/library/ms181154%28v=sql.105%29.aspx – Mihai

+0

Có lẽ bạn có thể cho chúng ta thấy một GIẢI THÍCH? –

Trả lời

0

Tôi muốn nhìn vào kế hoạch truy vấn ước tính trong SSMS (Ctrl + L). Nghi ngờ của tôi là nó không sử dụng một trong hai chỉ mục vì chúng không bao gồm.

hơn nữa trong trường hợp tùy chọn giảm dần chậm hơn, nó sẽ giới thiệu tùy chọn sắp xếp khác vì dữ liệu có thể đã được sắp xếp làm cho chiến lược kết nối đã chọn.

Nếu không nhìn vào kế hoạch truy vấn thực tế đây là tất cả chỉ là suy đoán hoang dã

+0

Bạn có cân nhắc không sử dụng ký tự đại diện (*) trong các lựa chọn của mình không? – KonB

0

bạn đã thử sử dụng chỉ là chỉ số tăng dần với thứ tự giảm dần bởi? Theo bài viết này, nó sẽ chỉ là nhanh như vậy để làm điều đó theo cách này là để có chỉ số tăng dần và thứ tự tăng dần bằng và loại bỏ sự cần thiết cho chỉ số giảm dần. Đánh giá một shot kể từ một thử nghiệm nhanh chóng. Building SQL Server Indexes in Ascending vs Descending Order

0

Tôi sẽ cố gắng mã hóa cứng các chỉ mục vào câu lệnh Chọn. Vì bạn có chỉ mục được xác định trước.

Cú pháp là

With (NOLOCK, Index(Index_Name)) 
2

Là một người dùng khác đã đề cập, đó là tất cả suy đoán hoang dã mà không nhìn thấy một kế hoạch truy vấn. Nhưng tôi sẽ ngạc nhiên nếu truy vấn sử dụng chỉ mục trong cả hai trường hợp. Ngay cả khi chúng bao gồm các chỉ mục, bạn vẫn đang lọc kết quả của một hàm cửa sổ trong truy vấn con, trình lập kế hoạch không có cách nào để biết các hàng nào hàm row_number sẽ trả về 100-110 cho đến khi nó phân tích toàn bộ tập kết quả trong truy vấn phụ và bạn chưa thực sự ra lệnh truy vấn con theo giá cả, vì vậy sẽ không có lợi ích nào trong nó bằng cách sử dụng một trong hai chỉ mục. Tôi không thể giải thích tại sao nó nhanh hơn trong trường hợp tăng dần trong những điều kiện này, mặc dù chúng ta sẽ phải xem một kế hoạch truy vấn để tìm ra điều đó, nhưng tôi nghi ngờ điều gì đó khác có thể đang diễn ra.

Có vẻ như bạn đang làm chức năng cửa sổ để thực hiện phân trang, nếu như vậy, và bạn đang sử dụng năm 2012 hoặc cao hơn, hãy thử sử dụng bù đắp/lấy thay vào đó, ví dụ:

select 
    b.*  
from 
    Books b (nolock) 
    inner join BookPublishRegions p (nolock) 
     on b.BookKey = bp.BookKey 
where  
    contains(p.PublishRegionName, 'France') 
order by price desc 
offset 100 fetch 10 

Các kế hoạch có thể nhận ra nó có thể sử dụng chỉ mục sau đó. Mặc dù nó có lẽ sẽ cần phải là một chỉ số nhóm hoặc bao phủ để tạo ra bất kỳ sự khác biệt nào là trung thực.

Nếu bạn đang sử dụng từ năm 2008 trở về trước, hãy thử đặt một thứ tự rõ ràng và nằm trong truy vấn con để trình lập kế hoạch nhận ra nó có thể sử dụng chỉ mục. Bạn vẫn có thể sử dụng chức năng cửa sổ và bộ lọc trong một truy vấn bên ngoài để thực hiện phân trang, nhưng cách này nó sẽ hy vọng chạy chức năng cửa sổ trên rất ít hàng:

select * from 
(
select top 110 
    (row_number() over (ORDER BY b.Price DESC)) as RowNumber, 
    b.*  
from 
    Books b (nolock) 
    inner join BookPublishRegions p (nolock) 
     on b.BookKey = bp.BookKey 
where  
    contains(p.PublishRegionName, 'France') 
ORDER BY b.Price DESC 
) as t1 
where t1.RowNumber between 100 and 110 
0

Hãy lấy một kế hoạch truy vấn bởi chỉ cần thêm "giải thích "trước truy vấn sql SELECT của bạn. Nó sẽ trả lời câu hỏi liệu các chỉ mục có được sử dụng cho việc đánh giá truy vấn hay không.

0

Cả hai trường hợp đều sử dụng các chỉ mục bạn đã đề cập? hoặc là ví dụ ASC sử dụng một chỉ mục khác mà không cần tìm kiếm khóa ". *".

Các vấn đề liên quan