服务器SQL2005查询分页语句你理解了么(一)

2014-11-24 15:31:21 · 作者: · 浏览: 0
服务器SQL2005查询分页语句你理解了么
在h31bt.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 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。
通过此处分析