11

我正在尝试编写一个数据库大小的查询结果分页。正如 SQL Server 2012 提供的那样OFFSET/FETCH,我正在使用它。但是在我将语句添加到我的查询之后,它需要 10 倍的时间。

查询:

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

第一个查询在 3 秒内返回结果,第二个在 47 秒内返回结果。执行计划不同,第二次的成本评估仅为7%,这对我来说完全没有意义:

执行计划

我需要帮助如何提高分页的性能。

4

1 回答 1

2

如果没有您的架构和数据,很难提出建议。在这 3 秒内,您至少应该能够做一件事。第一次查询和 47 秒。其次,将第一个查询的结果放入临时表中,然后将其用于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
于 2013-08-12T19:40:00.523 回答