【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);
}