如何使用总计数进行有效分页

时间:2016-04-19 06:22:27

标签: sql pagination laravel-3

我们有一个网络应用程序,可以帮助组织生物实验(用户描述实验和上传实验数据)。在主页面中,我们显示前10个实验,然后是下一个上一个下一个1 2 3 .. 30。

我告诉我如何有效地计算总数和分页。目前:

select count(id) from experiments; // not very efficient in large datasets

但是在处理大型数据线时这是如何扩展的? 200.000。我试图将随机实验导入到表中,但它仍然表现得相当不错(对于300.000次实验,为0.6秒)。

我想到的另一个选择是添加附加表statistics (column tableName, column recordsCount)。因此,在每次插入表experiments之后,我会在recordsCount中增加statistics(这意味着插入一个表并更新其他表,当然使用sql事务)。反之亦然,删除语句(recordsCount - )。

对于分页,最有效的方法是执行where id > last_id,因为sql当然使用索引。还有其他更好的方法吗?

如果要过滤结果,例如select * from experiment where name like 'name%',表statistics的选项失败。我们需要将总计数计为:select count(id) from experiment where name like 'name%'

应用程序是使用Laravel 3开发的,以防万一。

我想开发总是执行相同的分页。记录计数不得影响分页或记录总数。

1 个答案:

答案 0 :(得分:0)

请查询如下:

 CREATE PROCEDURE [GetUsers]    
(    
 @Inactive  Bit = NULL,    
 @Name   Nvarchar(500),    
 @Culture   VarChar(5) = NULL,    
 @SortExpression VarChar(50),    
 @StartRowIndex Int,    
 @MaxRowIndex Int,  
 @Count INT OUTPUT      
)    
AS    
BEGIN    



  SELECT ROW_NUMBER()    
   OVER    
   (    
    ORDER BY    

    CASE WHEN @SortExpression = 'Name' THEN [User].[Name] END,    
    CASE WHEN @SortExpression = 'Name DESC' THEN [User].[Name] END DESC    

   ) AS RowIndex, [User].*    
   INTO #tmpTable   
   FROM [User] WITH (NOLOCK)    
   WHERE (@Inactive IS NULL OR [User].[Inactive] = @Inactive)       
   AND (@Culture IS NULL OR  [User].[DefaultCulture] = @Culture)    
   AND [User].Name LIKE '%' + @Name + '%'     



 SELECT *    
 FROM #tmpTable WITH (NOLOCK)    
 WHERE  #tmpTable.RowIndex > @StartRowIndex     
 AND #tmpTable.RowIndex < (@StartRowIndex + @MaxRowIndex + 1)    

 SELECT @Count = COUNT(*) FROM #tmpTable             

 IF OBJECT_ID('tempdb..#tmpTable') IS NOT NULL  DROP TABLE #tmpTable;    
END