2013-08-12 30 views
9

Tôi đang cố viết phân trang theo kích thước cơ sở dữ liệu của kết quả truy vấn. Vì SQL Server 2012 cung cấp OFFSET/FETCH, tôi đang sử dụng nó. Nhưng sau khi tôi thêm câu lệnh vào truy vấn của mình, nó mất gấp 10 lần.Hiệu suất chậm khi sử dụng OFFSET/FETCH với Fulltext trong SQL Server 2012

Các truy vấn:

SELECT 
    p.ShopId, 
    count(1) as ProductsQuantity, 
    MIN(LastPrice) as MinPrice, 
    MAX(LastPrice) as MaxPrice 
FROM Product2 p WITH (NOLOCK) 
INNER JOIN 
    CONTAINSTABLE(Product2, ProductName, 'czarny') AS KEY_TBL 
ON KEY_TBL.[key]=p.Id 
WHERE 
    (p.LastStatus > 0 OR p.LastStatus = -1) 
GROUP BY p.ShopId 
ORDER BY p.ShopId asc 



SELECT 
    p.ShopId, 
    count(1) as ProductsQuantity, 
    MIN(LastPrice) as MinPrice, 
    MAX(LastPrice) as MaxPrice 
FROM Product2 p WITH (NOLOCK) 
INNER JOIN 
    CONTAINSTABLE(Product2, ProductName, 'czarny') AS KEY_TBL 
ON KEY_TBL.[key]=p.Id 
WHERE 
    (p.LastStatus > 0 OR p.LastStatus = -1) 
GROUP BY p.ShopId 
ORDER BY p.ShopId asc 
OFFSET 10 ROWS 
FETCH NEXT 10 ROWS ONLY 

Đầu tiên truy vấn trả về kết quả trong 3 giây, một giây trong 47 giây. kế hoạch thực hiện là khác nhau, và chi phí của thứ hai được đánh giá chỉ là 7%, những gì hoàn toàn làm cho không có ý nghĩa với tôi:

Execution plan

Tôi cần giúp đỡ làm thế nào để cải thiện hiệu suất của pagination.

+1

+1 cho câu hỏi này, chỉ cần ra khỏi factyou thêm một giải thích kế hoạch mà không cần bất cứ ai aksing cho nó và đây là thực sự là một vấn đề phân trang trong T-SQL gặp khá thường xuyên – Najzero

Trả lời

2

Thật khó để tư vấn mà không cần có lược đồ và dữ liệu của bạn trong tay. Có ít nhất một điều mà bạn sẽ có thể làm với những 3 giây. cho truy vấn đầu tiên và 47 giây. cho thứ hai, được đặt kết quả của truy vấn đầu tiên vào bảng tạm thời và sau đó sử dụng nó cho order by ... offset fetch next:

create table #tmp (Id int not NULL, Quantity int, MinPrice decimal(10,4), MaxPrice decimal(10,4), primary key clustered (Id)) 

insert into #tmp 
SELECT 
    p.ShopId, 
    count(1) as ProductsQuantity, 
    MIN(LastPrice) as MinPrice, 
    MAX(LastPrice) as MaxPrice 
FROM Product2 p WITH (NOLOCK) 
INNER JOIN 
    CONTAINSTABLE(Product2, ProductName, 'czarny') AS KEY_TBL 
ON KEY_TBL.[key]=p.Id 
WHERE 
    (p.LastStatus > 0 OR p.LastStatus = -1) 
GROUP BY p.ShopId 

select ShopId, ProductsQuantity, MinPrice, MaxPrice 
from #tmp 
ORDER BY ShopId asc 
OFFSET 10 ROWS 
FETCH NEXT 10 ROWS ONLY 
+0

giải pháp của bạn hoạt động tốt, tốc độ tương tự như trả về kết quả mà không cần phân trang. – adek

+0

Chỉ dành cho những người khác: tôi đã tìm thấy các phương pháp phân trang cũ hơn cho SQL Server, như được mô tả ở đây: http://www.mssqltips.com/sqlservertip/2696/comparing-performance-for-different-sql-server-paging-methods/ Tôi đã thử nghiệm chúng và kết quả là: 1. Phương pháp SQL 2000 (bảng tạm thời có nhận dạng): 32 giây 2. Phương pháp SQL 2005 (CTE với ROW_NUMBER()): 47 giây Vì vậy, sử dụng FETCH NEXT mà không có bảng tạm thời là giải pháp chậm nhất của tất cả. – adek

+0

Tôi không coi đây là một giải pháp thích hợp vì bạn vẫn đang tham gia với TẤT CẢ các kết quả của việc không ổn định và sau đó lấy và bỏ qua các hàng. Nhưng kết quả của tìm kiếm fulltext vẫn là đầu tiên sẽ nhận được tất cả các kết quả, và sau đó bạn đang cắt bỏ các kết quả này. Tôi biết rằng không ổn định có một cách để đưa những người đứng đầu chỉ bằng cách thêm 'chim sẻ', 10), nhưng tôi đã không tìm ra cách để bỏ qua điều này – WtFudgE

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