在sosobt.com网站准备采用Lucence.net来进行索引处理搜索慢问题的时候,突然发现常用的分页获取数据的row_number也支持不住了,后期查到200多万的时候非常慢(总数据有500万),经过网上查询分析一些资料后,基本上搞明白是什么原因导致的,顺便纪录一下解决方案。

------------------------------------

网上找的几种sqlserver2005高效分页sql查询语句
top方案:
sql codeselect top 10 * from table1
where id not in(select top 开始的位置 id from table1)

max:
sql codeselect top 10 * from table1
where id>(select max(id)
from (select top 开始位置 id from table1order by id)tt)

row:
sql codeselect *
from (
select row_number()over(order by tempcolumn)temprownumber,*
from (select top 开始位置+10 tempcolumn=0,* from table1)t
)tt
where temprownumber>开始位置
3种分页方式,分别是max方案,top方案,row方案

效率:
第1:row
第2:max
第3:top

缺点:
max:必须用户编写复杂sql,不支持非唯一列排序
top:必须用户编写复杂sql,不支持复合主键
row:不支持sqlserver2000

测试数据:
共320万条数据,每页显示10条数据,分别测试了2万页、15万页和32万页。

页码,top方案,max方案,row方案
2万,60ms,46ms,33ms
15万,453ms,343ms,310ms
32万,953ms,720ms,686ms

-----------------------------------------------

个人也是经常采用row_number来解决问题的,但是主键是以ID为主的,这次数据库表不是ID主键,

如果使用ID来进行获取200万后面的200条数据,发现服务器上需要几分钟都不一定出来得结果

select * from (select *,row_number() over(order by ID asc) as RowNum from H31_DHT_TYPE_101_1) as a where RowNum between 2000000  and  2000200

但是使用HashKey来排序,则很快,ms表示毫秒

select * from (select *,row_number() over(order by hashkey asc) as RowNum from H31_DHT_TYPE_101_1) as a where RowNum between 2000000  and  2000200

[2013-10-13 7:32:02]: Addindex[1011]:1500601 DBTime:219ms IndexTime:47ms
[2013-10-13 7:32:02]: Addindex[1011]:1500801 DBTime:219ms IndexTime:31ms
[2013-10-13 7:32:03]: Addindex[1011]:1501001 DBTime:547ms IndexTime:687ms
[2013-10-13 7:32:04]: Addindex[1011]:1501201 DBTime:219ms IndexTime:94ms
[2013-10-13 7:32:04]: Addindex[1011]:1501401 DBTime:219ms IndexTime:31ms
[2013-10-13 7:32:04]: Addindex[1011]:1501601 DBTime:219ms IndexTime:62ms
[2013-10-13 7:32:04]: Addindex[1011]:1501801 DBTime:219ms IndexTime:31ms
[2013-10-13 7:32:05]: Addindex[1011]:1502001 DBTime:219ms IndexTime:78ms
[2013-10-13 7:32:05]: Addindex[1011]:1502201 DBTime:219ms IndexTime:47ms
[2013-10-13 7:32:05]: Addindex[1011]:1502401 DBTime:218ms IndexTime:32ms

由于hashkey是唯一,但不是递增的问题,必须以ID递增来获取纪录增加到lucence索引里面,

在此查询了何时使用聚集索引或非聚集索引

下面的表总结了何时使用聚集索引或非聚集索引(很重要):

动作描述 使用聚集索引 使用非聚集索引
列经常被分组排序
返回某范围内的数据 不应
一个或极少不同值 不应 不应
小数目的不同值 不应
大数目的不同值 不应
频繁更新的列 不应
外键列
主键列
频繁修改索引列 不应
  主键 聚集索引
用途 强制表的实体完整性 对数据行的排序,方便查询用
一个表多少个 一个表最多一个主键 一个表最多一个聚集索引
是否允许多个字段来定义 一个主键可以多个字段来定义 一个索引可以多个字段来定义
     
是否允许 null 数据行出现 如果要创建的数据列中数据存在null,无法建立主键。
创建表时指定的 PRIMARY KEY 约束列隐式转换为 NOT NULL。
没有限制建立聚集索引的列一定必须 not null .
也就是可以列的数据是 null
参看最后一项比较
是否要求数据必须唯一 要求数据必须唯一 数据即可以唯一,也可以不唯一。看你定义这个索引的 UNIQUE 设置。
(这一点需要看后面的一个比较,虽然你的数据列可能不唯一,但是系统会替你产生一个你看不到的唯一列)
     
创建的逻辑 数据库在创建主键同时,会自动建立一个唯一索引。
如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,则建立主键时候,同时建立一个唯一的聚集索引
如果未使用 UNIQUE 属性创建聚集索引,数据库引擎 将向表自动添加一个四字节 uniqueifier 列。
必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。

通过此处分析聚焦索引一个表只能有一个,如何解决目前的问题呢?

首先我们分析下

select * from (select *,row_number() over(order by ID asc) as RowNum from H31_DHT_TYPE_101_1) as a where RowNum between 2000000  and  2000200

这条语句的对与错的问题,

1.select *,row_number() over(order by ID asc) as RowNum from H31_DHT_TYPE_101_1表明了需要查询所有字段和列全部搜索出来了,数据小的时候你不会发现,但数据量大的时候就知道了,因为他表明了获取所有字段的数据进行按ID排序,虽然ID也索引了。

2.上面需要很长时间,然后再去定位查询感觉时间很慢。

所以个人的想法是先不用查询出所有字段的数据,

WITH temp AS (SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS 'RowNumber' FROM H31_DHT_TYPE_101_1)

这条语句查询出来的结果需要1到2秒,比起上面的基本上需要很长时间算是好的了,

然后再从这里面取ID号,这样就节约了不少时间,

WITH temp AS (SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS 'RowNumber' FROM H31_DHT_TYPE_101_1)
select ID,hashKey,recvTime,updateTime,keyContent,keyType,recvTimes,fileCnt,filetotalSize,Detail,viewTimes,viewLevel from H31_DHT_TYPE_101_1 where id in (select id from temp where RowNumber between  2000000  and  2000200) 

分析使用的时间在2秒左右

[2013-10-14 2:43:17]: Addindex[1011]:2577092 DBTime:1453ms IndexTime:32ms
[2013-10-14 2:43:19]: Addindex[1011]:2577292 DBTime:1515ms IndexTime:32ms
[2013-10-14 2:43:20]: Addindex[1011]:2577492 DBTime:1578ms IndexTime:31ms
[2013-10-14 2:43:22]: Addindex[1011]:2577692 DBTime:1687ms IndexTime:32ms
[2013-10-14 2:43:23]: Addindex[1011]:2577892 DBTime:1422ms IndexTime:31ms
[2013-10-14 2:43:25]: Addindex[1011]:2578092 DBTime:1547ms IndexTime:31ms
[2013-10-14 2:43:27]: Addindex[1011]:2578292 DBTime:1469ms IndexTime:31ms
[2013-10-14 2:43:28]: Addindex[1011]:2578492 DBTime:1516ms IndexTime:31ms
[2013-10-14 2:43:30]: Addindex[1011]:2578692 DBTime:1422ms IndexTime:31ms
[2013-10-14 2:43:36]: Addindex[1011]:2578892 DBTime:6422ms IndexTime:31ms
[2013-10-14 2:43:40]: Addindex[1011]:2579092 DBTime:3938ms IndexTime:31ms
[2013-10-14 2:43:43]: Addindex[1011]:2579292 DBTime:3484ms IndexTime:32ms
[2013-10-14 2:43:48]: Addindex[1011]:2579492 DBTime:4265ms IndexTime:32ms
[2013-10-14 2:43:50]: Addindex[1011]:2579692 DBTime:1750ms IndexTime:31ms

总结:                                                                                                     

1.对SQL2005的分页进一步的了解了聚集索引的问题,有聚集索引的使用ROW_NUMBER则很快;

2.对目前大家所采用的分页语句是否合理的问题,优化的问题得了学习,特此记录一下。

3.希望写得不对的地方请大家在此留言指教下.

下一篇准备对网站采用lucence.net3.03如何来进行索引搞定搜索的问题进行记录。

大家看累了,就移步到娱乐区sosobt.com 去看看,休息下...

希望大家多多推荐哦...大家的推荐才是下一篇介绍的动力...

转载于:https://www.cnblogs.com/miao31/p/3368672.html

[搜片神器]服务器SQL2005查询分页语句你理解了么相关推荐

  1. jq取第一个子元素为select_Java修行第036天---MySQL中的子查询,分页语句,三大范式...

    学习目标: 1.掌握子查询 2.了解正则表达式 3.理解索引的作用和创建索引 4.了解用户管理 5.掌握分页语句 6.了解执行计划和数据库引擎 7.理解数据库设计的三大范式 综合程序图: 1 子查询知 ...

  2. mysql和sqlserver分页的区别_关于SQLServer和MySQL 查询分页语句区别

    首先来定义几个要用到的参数(例子) t_user数据表 int currentPage ; //当前页 int pageRecord ; //每页显示记录数 关于SqlServer数据库 分页SQL语 ...

  3. Hibernate→HQL、query.list()返回数据类型、查询相关语句、分页、原生SQL、@注解、持久化对象状态及生命周期、一多关系、继承映射关系、逆向工程

    HQL Query实例与表 session通用工具类 Query对象 from 类→List<类>接收 映射类 仅查询商品 查询商品及所在商家 别名 返回数据类型定义 Iterator接收 ...

  4. excel文档查询服务器,excel服务器数据库查询语句

    excel服务器数据库查询语句 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. ...

  5. JAVA中oracle分页语句,oracle分页查询语句,java得到分页查询语句的方法

    oracle分页查询语句 select * from ( select a.*, rownum rn from (select * from table_name) a where rownum &l ...

  6. oracle分页查询sql语句的rn,Mysql和Oracle中的分页SQL语句

    以前总结过一篇,Oracle分页查询语句的优化,当时对Oracle分页语句也着实花费了点时间记忆,不过今天在面试的时候,又考到了不同数据库的分页sql语句,对Oracle数据库的书写又存在了问题,以为 ...

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

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

  8. column ambiguously defined oracle数据库分页语句查询中select嵌套时出错

    column ambiguously defined &oracle数据库分页语句查询中select嵌套时出错 转载于 [ lev草梦的博客](http://blog.sina.com.cn/ ...

  9. oracle分页查询sql语句通用,oracle分页查询sql语句,oracle分页查询sql语句详解

    oracle分页查询sql语句,oracle分页查询sql语句详解,Oracle分页查询sql语句 Oracle中分页和MySql中的分页不同,MySql中的分页使用关键字limit即可,相对简单一点 ...

  10. 查询分页的几种sql语句

    sql server 中的分页查询sql语句不跟mysql 一样,mysql 用 limit 可以实现查询sql分页.如: select * from news where id>=(selec ...

最新文章

  1. Windows10 右键 cmd
  2. Scala键盘录入代码示例
  3. 技术人员职业生涯的红色警报
  4. Java8使用 Optional 处理 null
  5. Windows驱动程序开发语言
  6. 在eclipse中启动Tomcat访问localhost:8080失败项目添加进Tomcat在webapp中找不到
  7. 【计算机视觉】运动目标检测算法文献阅读笔记
  8. Spring 的事务隔离级别和传播特性
  9. 荷兰音乐组合Bassjackers将在Origin上发布6条NFT曲目
  10. mac python2.7升级到3.7_Mac 升级 Python2.7 到 Python3.5
  11. 树状排序(目录结构)
  12. 购物直播APP系统+短视频系统开发方案
  13. Mac 系统mysql密码重置
  14. 京东实习笔试——站队
  15. 美国贝勒大学计算机科学专业怎么样,贝勒大学专业排名一览(含历年专业排名信息,USNEWS美国大学排名版)...
  16. HTML5中新增的元素有哪些
  17. 关于解决移动端息屏后定时器不工作的问题
  18. Win Server 系统远程桌面连接失败解决办法
  19. airpods耳机敲击没反应_airpods怎么敲击切歌_airpods如何设置敲击切歌
  20. 【OpenJudge】反反复复

热门文章

  1. PHP 日期 加减 月数,天数,周数,小时,分,秒等等
  2. java中eq、ne、gt、lt、ge、le分别代表含义
  3. java sqlite 密码保护_密码保护SQLite数据库 . 可能吗?
  4. python如何制作一个任意列表_我要悄悄学Python之列表(一)
  5. 基于决策树的保险案列
  6. Linux入门之常用命令(10)软连接 硬链接
  7. nested exception is java.io.FileNotFoundException: class path resource [spring/spring-datasource-mog
  8. 函数式编程(一) 认识“编程范式”和“函数”
  9. java自定义异常和throw、throws的使用
  10. hdu1711 Number Sequence kmp模板