热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SQLServer分页控件优化:高效分页算法详解

两个分页算法,第一个分页算法只适用于SQL Server ,第二个分页算法Access也能用。速度还是比较快的,基本上几十毫秒就可以搞定。至于是不是写成存储过程的形式,看个人的习惯了,我是在程序里面组

两个分页算法,第一个分页算法只适用于SQL Server ,第二个分页算法Access也能用。
速度还是比较快的,基本上几十毫秒就可以搞定。
至于是不是写成存储过程的形式,看个人的习惯了,
我是在程序里面组合sql语句,并且封装到了分页控件里面,这样就方便多了,尤其是在多查询条件和算法升级的时候。


上两篇随笔:
我的分页控件(未完,待续)——控件件介绍及思路

我自己写的一个分页控件(源码和演示代码)PostBack分页版 for vs2003、SQL Server

关于分页的误区
    误区1:分页的时候,只有使用存储过程,效率才高。
    误区2:忽略了索引的作用。

上两篇好像介绍的不太详细,这里详细说明一下分页控件里使用的分页算法,也就是SQL语句。

分页一般分为四种情况

1、单字段排序,排序字段没有重复值。
2、单字段排序,排序字段有重复值。
3、多字段排序,最后一个排序字段没有重复值。
4、多字段排序,最后一个排序字段有重复值。

其中第2、4 情况都可以再加一个排序字段(比如说主键),就可以转换成第三种情况。

所以分页针对1、3两种情况设置了两种分页算法。

1、单字段排序,排序字段没有重复值。

    公式:

 1分页控件之分页算法 —— for SQL Server 版。 - 文章图片declare @col int
 2分页控件之分页算法 —— for SQL Server 版。 - 文章图片
 3分页控件之分页算法 —— for SQL Server 版。 - 文章图片select top {PageSize * (PageIndex-1)+1} @col = [排序字段] 
 4分页控件之分页算法 —— for SQL Server 版。 - 文章图片from [表名|视图名] 
 5分页控件之分页算法 —— for SQL Server 版。 - 文章图片[ where 查询条件 ] 
 6分页控件之分页算法 —— for SQL Server 版。 - 文章图片order by [排序字段] asc|desc
 7分页控件之分页算法 —— for SQL Server 版。 - 文章图片
 8分页控件之分页算法 —— for SQL Server 版。 - 文章图片select top PageSize 需要显示的字段 
 9分页控件之分页算法 —— for SQL Server 版。 - 文章图片from [表名|视图名] 
10分页控件之分页算法 —— for SQL Server 版。 - 文章图片where [排序字段] >= @col
11分页控件之分页算法 —— for SQL Server 版。 - 文章图片[ and 查询条件 ]
12分页控件之分页算法 —— for SQL Server 版。 - 文章图片order by [排序字段] asc|desc


    以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照ProductID 倒序,如果想显示第二页的数据,那么SQL语句就是
    

分页控件之分页算法 —— for SQL Server 版。 - 文章图片declare @col int
分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片select top 11 @col = ProductID from Products where CategoryID = 3 order by ProductID desc    
分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片select top 10 * from Products where ProductID >= @col and CategoryID = 3 order by ProductID desc    


   说明:
    第一行的定义,要根据字段类型来修改,看是比较麻烦,但是这个麻烦交给分页控件就可以了,使用者,只要设置分页控件的属性就可以了。
    第五行和第十一行,如果需要加查询条件的话就可以在这里添加。

    第三行是一个“定位”,这个可以算是SQL Server 所特有的吧,也是SQL Server 很宽容的地方。以Products 表的例子,执行完第一条select 语句之后, @col 里面记录的是 在CategoryID = 3 的记录里面,按照ProductID 倒序,排行在11位的记录的值。
    
    第一个select 语句定位以后,第二个select 语句就可以根据这个“位置”继续向下查找数据了。

    虽然例子里面使用了ProductID(主键)来排序,但是并不是说这个算法只能用主键来排序,哪个字段都可以,但是要符合第一种情况,就是“只有一个排序字段,且排序字段里的记录没有重复值”!


3、多字段排序,最后一个排序字段没有重复值。

    如果 Products 表想要用 UnitPrice 字段来排序怎么办呢?上面的算法是不适合的,我们需要使用另一种算法,这个和颠颠倒倒法有些类似,但是我做了一些优化。

    公式:

分页控件之分页算法 —— for SQL Server 版。 - 文章图片select [需要显示的字段] from [表名|视图名] where [主键字段] in 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    ( select top PageSize [主键字段] from 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片        (select top {PageSize * PageIndex} [主键字段] , [排序字段] from     --有几个排序字段就写几个字段
分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            [表名|视图名] 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            [ where 查询条件 ] 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            order by 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                [排序字段1] asc|desc ,
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                [排序字段2] desc|asc, 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                分页控件之分页算法 —— for SQL Server 版。 - 文章图片分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                [主键字段] asc|desc     
分页控件之分页算法 —— for SQL Server 版。 - 文章图片        ) as aa     
分页控件之分页算法 —— for SQL Server 版。 - 文章图片        order by     
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            [排序字段1] desc|asc,        --如果上面是倒序,那么这里就是正序,下同
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                [排序字段2] asc|desc ,
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                    分页控件之分页算法 —— for SQL Server 版。 - 文章图片分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                    [主键字段] desc|asc 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    ) 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片order by 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    [排序字段1] asc|desc,    --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    [排序字段2] desc|asc,
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    分页控件之分页算法 —— for SQL Server 版。 - 文章图片分页控件之分页算法 —— for SQL Server 版。 - 文章图片
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    [主键字段] asc|desc


    以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照UnitPrice 倒序,由于UnitPrice 字段可能有重复值,所以加上一个排序字段——ProductID ,即按照 UnitPrice  desc,ProductID  来排序。 如果想显示第二页的数据,那么SQL语句就是

分页控件之分页算法 —— for SQL Server 版。 - 文章图片select * from Products where ProductID in 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    ( select top 10 ProductID from 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片        (select top 20 ProductID , UnitPrice from     
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            Products 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            where CategoryID = 3
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            order by 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                UnitPrice desc ,
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                ProductID      
分页控件之分页算法 —— for SQL Server 版。 - 文章图片        ) as aa     
分页控件之分页算法 —— for SQL Server 版。 - 文章图片        order by     
分页控件之分页算法 —— for SQL Server 版。 - 文章图片            UnitPrice asc,        --如果上面是倒序,那么这里就是正序,下同
分页控件之分页算法 —— for SQL Server 版。 - 文章图片                ProductID desc 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    ) 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片order by 
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    UnitPrice desc,    --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。
分页控件之分页算法 —— for SQL Server 版。 - 文章图片    ProductID 


    说明:
    1、这里查询条件加一次就可以了。
    2、是不是看 asc|desc 倒来倒去的有点晕,恩,这就对了,颠颠倒倒嘛。
    3、最主要的就是第三个select 语句,他要取从第一条数据到要显示的页的数据,可见越是后面的记录,top n 就会越大,所以这里提取的数据就要做一个精简,只写排序需要的字段(主键字段和排序字段)。
    4、第二个select 语句是去掉前面不需要的页里的数据,只保留要显示的页号里的数据。
    5、第一个select 语句,用主键字段 in () 的方式提取其他需要的字段。
    6、这种分页算法有一个小的bug,就是显示最后一页数据的时候,会多出来几条记录,不过这个bug已经在分页控件里面修正了,最后一页的分页算法,采用特殊的select语句。
    7、效率,设置好索引,效率是没有问题的,上一篇随笔已经测试过了。
    8、这种算法有一个“侵入性”,就是要求表必须有主键,而且不能是联合主键,引为要用 in 的方式查询数据。但是并没有要求主键自身必须能够排序。

测试效果
记录数:2523136条。
一页显示5条记录。

//分页算法1 单字段排序,且排序字段是聚集索引。
   //1000 页以内 15毫秒
   //10000页以内 30毫秒
   //50000页以内 100多毫秒
   //100000页以内 200多毫秒
   //最后几页 第一次跳转到 4秒多
   //最后几页 连续向前翻页 1秒156毫秒

   //页号大范围跳转的时候需要的时间比较长,但是也小于1秒,同时SQL Server 占用的内存有所增加 120M。最后几页时达到320M

===================================================================
以下是多排序字段的分页情况,排序字段是 UnitPrice,ProductID  

   //分页算法2 无索引  首页 8秒187毫秒 。 
   //10 页以内 2秒812毫秒
   //速度太慢下面的就不测试了

   //分页2 非聚集索引 UnitPrice  首页 468毫秒
   //10 页以内 2秒671毫秒
   //速度太慢下面的就不测试了

   
   //分页算法2 非聚集索引 UnitPrice,ProductID  首页 500毫秒
   //10 页以内 2秒796毫秒
   //100页以内 4秒796毫秒
   //速度太慢下面的就不测试了

   
   //分页算法2 非聚集索引 UnitPrice,ProductID desc  首页 500毫秒
   //10 页以内 0-15毫秒
   //100页以内 15-46毫秒
   //1000页以内 31-62毫秒
   //10000页以内 100毫秒左右
   //50000页以内 400-500毫秒
   //100000页以内 900毫秒左右
   //最后几页 第一次跳转到 4秒421毫秒
   //最后几页 连续向前翻页 4秒375毫秒

   //页号大范围跳转的时候需要的时间比较长,但是也小于1秒,
   //这回SQL Server 占用的内存增加幅度不大 120M左右






推荐阅读
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 机器学习中的相似度度量与模型优化
    本文探讨了机器学习中常见的相似度度量方法,包括余弦相似度、欧氏距离和马氏距离,并详细介绍了如何通过选择合适的模型复杂度和正则化来提高模型的泛化能力。此外,文章还涵盖了模型评估的各种方法和指标,以及不同分类器的工作原理和应用场景。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 在使用SQL Server进行动态SQL查询时,如果遇到LIKE语句无法正确返回预期结果的情况,通常是因为参数传递方式不当。本文将详细探讨这一问题,并提供解决方案及相关的技术背景。 ... [详细]
author-avatar
ltl3265164
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有