数据库分页设计

时间:2010-07-01 09:42:37

标签: sql

我正在为我的网格提取数据

SELECT
   Orders.CustomerID,
   Orders.OrderTime,
   OrderItems.ProductID,
   OrderItems.Quantity
   FROM
   dbo.Orders INNER JOIN dbo.OrderItems
       ON Orders.ID = OrderItems.OrderID

我还需要分页的总数。

有两种选择。

1-做另一次获取

SELECT count(*) FROM dbo.Orders

2-将count语句放入查询

SELECT
   Orders.CustomerID,
   Orders.OrderTime,
   OrderItems.ProductID,
   OrderItems.Quantity,
   (SELECT count(*) FROM dbo.Orders) as Count
   FROM
   dbo.Orders INNER JOIN dbo.OrderItems
       ON Orders.ID = OrderItems.OrderID

我应该走哪条路?

5 个答案:

答案 0 :(得分:2)

在您提出的两种方法中,第一种(单独查询)更好。第二种方法意味着计数将出现在返回的每一行中,这有点不必要。此外,如果查询返回20行,select count(*)将执行20次(如果我没记错的话,猜测这可能取决于你正在使用的数据库引擎)。

此外,根据您正在设想的流量以及表格可能获得的大小,您可以通过在某处缓存select count(*)的结果,然后在插入/删除时刷新它来改进此桌子。

答案 1 :(得分:2)

如果这是针对SQL Server 2005或更高版本,则获取分页的最佳方法之一是使用Common Table Expression

CREATE PROC MyPaginatedDataProc
@pageNumber INT
AS

WITH OrdersCTE (CustomerID, OrderTime, ProductID, Quantity, RowNumber)
AS
(
    SELECT
        Orders.CustomerID,
        Orders.OrderTime,
        OrderItems.ProductID,
        OrderItems.Quantity,
        ROW_NUMBER() OVER (ORDER BY OrderItems.OrderID) AS RowNumber
    FROM
        dbo.Orders INNER JOIN dbo.OrderItems ON Orders.ID = OrderItems.OrderID
)

SELECT
    CustomerID,
    OrderTime,
    ProductId,
    Quantity
FROM
    OrdersCTE
WHERE
    RowNumber BETWEEN (@pageNumber * 10) AND (((@pageNumber + 1) * 10) -1)

否则为了获得总行数,我会使用像Mailslut这样的单独查询。

答案 2 :(得分:1)

如果您使用oracle ,则可以使用COUNT(*) OVER ( ) CNT。这个更有效率 因为需要单表扫描

   SELECT
   Orders.CustomerID,
   Orders.OrderTime,
   OrderItems.ProductID,
   OrderItems.Quantity,
   COUNT(*) OVER ( ) CNT as Count
   FROM
   dbo.Orders INNER JOIN dbo.OrderItems
       ON Orders.ID = OrderItems.OrderID

答案 3 :(得分:1)

正如@Mailslut建议的那样,你应该使用两个查询。但是,您应该添加一个 获取数据的查询的WHERE子句,因此您只获取实际需要显示的数据(除非您正在缓存它)。

如果一次有多个线程访问数据库,您还需要以某种方式确保计数与数据库保持同步。

答案 4 :(得分:1)

我会考虑不同的东西,因为你要做的不是很简单,而是非常必要。您是否考虑过使用SQL Server row_number函数?通过这种方式,您可以通过查看返回的max row_number以及您想要的顺序来了解有多少条记录。

SELECT
   Orders.CustomerID,
   Orders.OrderTime,
   OrderItems.ProductID,
   OrderItems.Quantity,
   ROW_NUMBER() OVER(ORDER BY Orders.CustomerId) rn
   FROM
   dbo.Orders INNER JOIN dbo.OrderItems
       ON Orders.ID = OrderItems.OrderID