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

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

------------------------------------数据库

网上找的几种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)sqlserver

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,686msspa

-----------------------------------------------.net

我的也是常常采用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 去看看,休息下...

 

但愿你们多多推荐哦...你们的推荐才是下一篇介绍的动力...

相关文章
相关标签/搜索