【数据分页】

SqlServer高效分页查询

-- =============================================
-- Author:xxx
-- Create date: xxx
-- Description:	查询一个用户的发帖信息
-- =============================================
ALTER PROCEDURE [dbo].[p_Page_UserID]
@pageindex int,
@pagesize int ,
@UserID uniqueidentifier
AS
BEGIN
	SELECT * FROM
	(
		SELECT TOP (@pageindex*@pagesize) row_number() over(
			order by PostAddTime DESC
		) n,* from xyl_UserPost  WHERE PostUserID = @UserID AND PostState=1
	) hhh 
	where hhh.n > @PageSize * (@pageIndex - 1)
	and hhh.n <= @PageSize * @pageIndex
	SELECT COUNT(*) FROM xyl_UserPost WHERE PostUserID=@UserID AND  PostState=1
END

Sql Server分页分段查询百万级数据四种项目实例

第一种、使用NOT IN关键字

SELECT TOP 50 * FROM infoTab WHERE ID NOT IN(SELECT TOP 100000 ID FROM infoTab)

平均查询时间0.1s。这是非常简单的一种写法,效率还可以,只是使用默认ID排序,如果ID有间断,展示效果不好。

第二种、通过升序与降序方式实现分页查询

SELECT * FROM (SELECT TOP 50 * FROM (SELECT TOP 100050 * FROM infoTab ORDER BY ID ASC)TEMP1 ORDER BY ID DESC)TEMP2 ORDER BY ID ASC

平均查询时间0.22s。这种是利用先查询倒序的50个数据,最后又进行升序排序的方法很复杂,不推荐使用,也最浪费时间,效率最低。

第三种、采用MAX(ID)函数

实际是关于MIN()函数和MAX()函数的使用

SELECT TOP 50 * FROM infTab WHERE ID>(SELECT MAX(ID) FROM (SELECT TOP 100000 ID FROM infoTab ORDER BY ID)temp) 

平均查询时间0.13s。这种方法理解起来很简单,就是直接使用MAX()进行查找,然后id大于MAX()结果为100000的前50条记录即为结果。

第四种、最后一种推荐使用的方法,使用ROW_NUMBER

正如Oracle的rowid,解决了整型的ID字段不连续的问题。用行号(ROW_NUMBER)查询,比较高效的查询方式,只有在SQL Server2005或更高版本才支持。

注意的是,ROW_NUMBER后面必须跟着OVER(ORDER BY [FIELD]),我们来看具体的写法。

SELECT * FROM (SELECT TOP 100050 ROW_NUMBER() OVER(ORDER BY ID ASC) AS rowid,* FROM infoTab)t WHERE t.rowid > 100000

平均运行时间0.29s。这种方法的好处是实现连续的排序ROWID,避免了ID间断不连续的问题,展示更加美观。

  在这里面需要注意的是OVER的括号里面可以写多个排序字段,比如:OVER(ORDER BY CreatedTime, ID)。

如果使用下面这条语句更高效,是上面语句运行时间的三分之一,平均运行时间仅0.08s。

SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY ID ASC) AS rowid,* FROM infoTab)t WHERE t.rowid > 100000 AND t.rowid <= 100050

 

总之,我们推荐使用第四种方法中的后面一条语句,查询效率高,而且展示结果美观,ROWID连续,尤其在千万级数据查询的时候,效率相差很大非常大。

【LinQ】

Skip((pageIndex - 1) * pageSize):忽略当前页之前的记录

Take(pageSize):读取指定数量的记录,也就是当前页的记录

IList<Test> list = this.DbContext.Set<Test>()
    .Where(m => m.ProjectID == projectId && m.Assigner == assigner)
    .OrderByDescending(m => m.ID)
    .Skip((pageIndex - 1) * pageSize)
    .Take(pageSize)
    .ToList();

【使用 LINQ 对大型结果集进行分页】

适用于: Dynamics 365 (online),Dynamics 365 (on-premises),Dynamics CRM 2016,Dynamics CRM Online

您可以使用 Take 和 Skip 运算符对大型 .NET 语言集成查询 (LINQ) 查询的结果进行分页。Take 运算符会检索指定数量的结果,而 Skip 运算符会跳过指定数量的结果。

int pageSize = 5;

var accountsByPage = (from a in svcContext.AccountSet
                      select new Account
                      {
                       Name = a.Name,
                      });
System.Console.WriteLine("Skip 10 accounts, then Take 5 accounts");
System.Console.WriteLine("======================================");
foreach (var a in accountsByPage.Skip(2 * pageSize).Take(pageSize))
{
 System.Console.WriteLine(a.Name);
}




 

猜你喜欢

转载自blog.csdn.net/mr_xuzhe/article/details/80887826
今日推荐