SqlServer常用的几种分页查询SQL语句介绍、对比以及在.Net下的使用

前言

    在实际开发过程中,当数据量比较多的时候,大量的数据一下子展示到页面上是非常不可取的。所以我们通常要进行分页(这里的分页是指真分页),而不是前端JS实现的假分页。

    最近的学习过程中,使用ASP.NET MVC配合Layui框架进行开发时,根据Layui Page传回的参数要进行分页操作(虽然EntityFramework提供了非常便捷的分页方法,但是SQL什么时候都不能忘掉吧O(∩_∩)O哈哈~)。索性对于分页SQL这一块,自己做一个系统的总结。

    本篇博客针对于SQL Server数据库进行讨论

一、三种分页SQL语句的介绍和写法

     示例数据库的字段:

     假设有100条数据,每页显示10条,我们取第3页数据来说

     

     这里按照三种SQL的的破壳日从古到今进行介绍叭!

     1.top+嵌套查询

      介绍:简单的来说就是,我们需要第21-30条数据,我们先查前20条id为一个集合,再从原表中取id不在这个集合中的前十条;

       写法:

select top 10 * from BigDataTable where id not in(select top 20 id from BigDataTable order by id) order by id

       注:

       两个排序字段要保持一致!

     2.ROW_NUMBER()开窗函数(支持SqlServer 2005版本以上)

   介绍:通过ROW_NUMBER()生成序号列,根据序号列取需要数据

   写法:我一般建立一个视图(#^.^#)

  create view View_Page
  as
  select *,ROW_NUMBER()over(order by id) as rowindex from BigDataTable
  SELECT * FROM View_Page WHERE rowindex>=21 AND rowindex<=30

3.offset fetch(SqlServer 2012 版本以上)

   介绍:offset x rows=>跳过前x行 fetch next y rows=>取之后的y行

   写法:

SELECT * FROM BigDataTable ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY

          注意:一定要排序吖!

二、对比

     本部分,我们用了一个含有1028135条数据的数据库。

     分别使用上述三种SQL来取得1000001-1000020条数据来进行对比。

     数据如下:

  1.使用top+嵌套查询执行结果如下:

   取十次查询时间求平均值:(1.023+0.988+0.949+0.960+1.028+1.002+0.957+0.956+0.961+0.964)/10 =0.9788s

   2.使用ROW_NUMBER()开窗函数执行结果如下:

   取十次查询时间求平均值:(0.839+0.841+0.845+0.840+0.853+0.845+0.828+0.861+0.874+0.861)/ 10=0.8487s

  3.offset fetch执行结果如下:

  取十次查询时间求平均值:(0.356+0.358+0.322+0.322+0.350+0.325+0.355+0.315+0.328+0.330)/ 10=0.3361s

 注:这里进行的对比这是大概结论呢,因为我们没有排除以主键,聚集索引作为排序字段带来的影响。

从上可以大致得出,效率:top+嵌套查询<ROW_NUMBER()<offset fetch

从我前面说的它们的破壳日来看,时代在不断进步,微软的工程师们也在不断进步提升O(∩_∩)O哈哈~

三、在ASP.NET下的简要说明

 上面我们直接拿了具体的SQL语句来进行说明,这样更直观便于理解,实际上我们在开发过程中不考虑框架自带的方法,一般需要写成存储过程,后台传入相应参数进行调用。

1.在ASP.NET WebForm下

     ASP.NET WebForm项目中,我们常常采用三层架构模式进行开发。

     那么我们若想实现分页效果(不考虑ASP.NET WebForm Pager控件,以及GridView自带的分页效果),我们一般需要在DAL层中通过SQLHelper使用ADO.NET调用封装以上SQL语句的存储过程拿到分页后的数据,后台将分页后的数据展示给前台。

2.在ASP.NET MVC下

    ASP.NET MVC项目中,我们通常会使用EntityFramework放入Model层中操作数据。

   EntityFramework中提供了两个分页的方法,Skip()、Take(),使用这两个方法前要进行OrderBy()操作。当时堂课上学习的时候我就猜测,这一定是在数据库中执行了分页SQL的一种。

  通过SqlServer Profiler对数据库跟踪,调用Skip()、Take()结束延迟加载之后,数据库中执行了offset fetch分页语句

 注:不是一定就是执行offset fetch分页SQL!

 在我的环境VisualStudio 2017+SqlServer 2014下 执行的是offset fetch分页语句

 在VisualStudio 2013+SqlServer 2008R2下 执行的是ROW_NUMBER()分页语句

四、结语

    以上就是我在大学期间,了解和掌握的SqlServer下的三种分页语句的使用、看法以及在.NET下的应用和一些见解,并且在百万数据下的简单的效率对比。

   花了近两个小时去写这个文章,是自己对这块知识做得一个笔记也是对分页SQL做了一个系统性的总结。虽然现在分页组件(MvcPager等),简单引入DLL,传入几个参数便可实现很好的分页效果。但是,我觉得我们知道怎么去用,也需要了解究竟是怎么一回事。作为一个学生,这些基本功夫还是需要扎实、牢固,技术才能不断得到提升!

 这些都是在课堂上以及平时开发过程中,自己的认识。可能不够严谨和准确,需要详细了解可以阅读微软官方文档进一步学习!


       
 

发布了2 篇原创文章 · 获赞 9 · 访问量 378

猜你喜欢

转载自blog.csdn.net/qq_42077395/article/details/104639145