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   and  

但是使用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   and  
[-- ::]: Addindex[]: DBTime:219ms IndexTime:47ms
[-- ::]: Addindex[]: DBTime:219ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:547ms IndexTime:687ms
[-- ::]: Addindex[]: DBTime:219ms IndexTime:94ms
[-- ::]: Addindex[]: DBTime:219ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:219ms IndexTime:62ms
[-- ::]: Addindex[]: DBTime:219ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:219ms IndexTime:78ms
[-- ::]: Addindex[]: DBTime:219ms IndexTime:47ms
[-- ::]: Addindex[]: 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   and  

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

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 and )

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

[-- ::]: Addindex[]: DBTime:1453ms IndexTime:32ms
[-- ::]: Addindex[]: DBTime:1515ms IndexTime:32ms
[-- ::]: Addindex[]: DBTime:1578ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:1687ms IndexTime:32ms
[-- ::]: Addindex[]: DBTime:1422ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:1547ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:1469ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:1516ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:1422ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:6422ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:3938ms IndexTime:31ms
[-- ::]: Addindex[]: DBTime:3484ms IndexTime:32ms
[-- ::]: Addindex[]: DBTime:4265ms IndexTime:32ms
[-- ::]: Addindex[]: DBTime:1750ms IndexTime:31ms

总结:                                                                                                     

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

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

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

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

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

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

[搜片神器]服务器SQL2005查询分页语句你理解了么的更多相关文章

  1. Sql Server系列:查询分页语句

    1 利用临时表分页 分页存储过程: CREATE PROCEDURE [USP_Product_GetPaged] ), ), @PageIndex INT, @PageSize INT AS BEG ...

  2. 跨服务器查询sql语句样例

    若2个数据库在同一台机器上:insert into DataBase_A..Table1(col1,col2,col3----)select col11,col22,col33-- from Data ...

  3. 分页用到的子查询sql语句

    说明(2017-8-31 23:30:22): 1. 分页用到的子查询sql语句 select * from(select *,ROW_NUMBER() over(order by id)as num ...

  4. 跨服务器查询sql语句样例(转)

    若2个数据库在同一台机器上: insert into DataBase_A..Table1(col1,col2,col3----) select col11,col22,col33-- from Da ...

  5. Oracle、MySQL和SqlServe分页查询的语句区别

    ★先来定义分页语句将要用到的几个参数: int currentPage ; //当前页 int pageRecord ; //每页显示记录数 以之前的ADDRESSBOOK数据表为例(每页显示10条记 ...

  6. 查询分页的几种Sql写法

    查询分页的几种Sql写法 摘自:http://www.cnblogs.com/zcttxs/archive/2012/04/01/2429151.html 1.创建测试环境,(插入100万条数据大概耗 ...

  7. [C#搜片神器] 之P2P中DHT网络爬虫原理

    继续接着上一篇写:使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)[搜片神器] 昨天由于开源的时候没有注意运行环境,直接没有考虑下载BT种子文件时生成子文件夹,可能导致有的朋友运行 ...

  8. [搜片神器]之DHT网络爬虫的代码实现方法

    继续接着第一篇写:使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)[搜片神器] 谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器: http://www.sosobta. ...

  9. [搜片神器]之DHT网络爬虫的C++程序初步开源

    回应大家的要求,特地整理了一开始自己整合的代码,这样最简单,最直接的可以分析流程,至于文章里面提供的程序界面更多,需要大家自己开发. 谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器: ht ...

随机推荐

  1. WinFrom“动态”WebService

    1.首先添加一个WebService: 2.输入地址....Ok: 3.在WebService用到的类上按F12: 4.进入类中,找到其构造函数: 5.修改其构造函数为代参数,并且让this.Url= ...

  2. android app性能优化大汇总(google官方Android性能优化典范 - 第2季)

    Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的 ...

  3. 在rdlc 中 显示成 yyyy年MM月dd日

    在rdlc 中  显示成  yyyy年MM月dd日, 采用: =First(Format(Fields!添加时间.Value,"yyyy年MM月dd日")  )

  4. jquery 导航固定的一个实例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 15条JavaScript最佳实践很经典噢

    感觉比较经典,特转载腾讯大讲堂.本文档整理大部分公认的.或者少有争议的JavaScript良好书写规范(Best Practice).一些显而易见的常识就不再论述(比如要用对象支持识别判断,而不是浏览 ...

  6. GridView自带分页 1总页数 首页 下一页 上一页 尾页 X 页 go 实现方法 .

    在前台GRIDVIEW中添加如下代码 <PagerTemplate> <table> <tr> <td style="text-align: rig ...

  7. Java实现邮箱找回密码 --转载

    通过邮件找回密码功能的实现 1.最近开发一个系统,有个需求就是,忘记密码后通过邮箱找回.现在的系统在注册的时候都会强制输入邮箱,其一目的就是 通过邮件绑定找回,可以进行密码找回.通过java发送邮件的 ...

  8. NSString字符操作

    1.常用创建初始化方法 1.NSString *string0 = @"string"; 2.NSString *string1 = [NSString stringWithFor ...

  9. 生动详细解释javascript的冒泡和捕获,包懂包会(转)

    前言:虽然精通jquery,但对它的原型javascript却不是很了解,最近在学习javascript中遇到了一些困难,比如冒泡和捕获,很多次被提到,但又不知究竟应用在何处.找到了一些好文章解惑,在 ...

  10. 19款绚丽实用的jQuery/CSS3侧边栏菜单

    jQuery作为一款主流的JavaScript前端开发框架,深受广告开发者的亲睐,同时jQuery有着不计其数的插件,特别是菜单插件更为丰富,本文将要为大家介绍20个绚丽而实用的jQuery侧边栏菜单 ...