实现千万级数据的分页显示--整理资料并测试

原帖子如下:

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*
InBlock.gif 名称:spAll_DeleteNoneUnique
InBlock.gif 输入:要查询的表名和字段列表
InBlock.gif 输出:
InBlock.gif 调用:
InBlock.gif 说明:实现千万级数据的分页显示!--可以在5秒内获取1448万条记录里的第1200页的100条记录,雄不?
InBlock.gif 作者:铁拳
InBlock.gif 邮件:
InBlock.gif 网站:http://www.wellknow.net
InBlock.gif 更新:20040610
InBlock.gif 支持:http://bbs.wellknow.net
InBlock.gif 版权:转述时请注明来源:用思维创造未来的Wellknow.net
ExpandedBlockEnd.gif
*/

None.gif
None.gif
CREATE   PROCEDURE  GetRecordFromPage
None.gif    @tblName      
varchar ( 255 ),        --  表名
None.gif
    @fldName       varchar ( 255 ),        --  字段名
None.gif
    @PageSize      int   =   10 ,            --  页尺寸
None.gif
    @PageIndex     int   =   1 ,             --  页码
None.gif
    @IsCount       bit   =   0 ,             --  返回记录总数, 非 0 值则返回
None.gif
    @OrderType     bit   =   0 ,             --  设置排序类型, 非 0 值则降序
None.gif
    @strWhere      varchar ( 1000 =   ''    --  查询条件 (注意: 不要加 where)
None.gif
AS
None.gif
None.gif
declare  @strSQL    varchar ( 6000 )        --  主语句
None.gif
declare  @strTmp    varchar ( 100 )         --  临时变量
None.gif
declare  @strOrder  varchar ( 400 )         --  排序类型
None.gif

None.gif
if  @OrderType  !=   0
None.gif
begin
None.gif    
set  @strTmp  =  " < ( select   min "
None.gif    
set  @strOrder  =  "  order   by   [ " + @fldName +" ]   desc "
None.gif
end
None.gif
else
None.gif
begin
None.gif    
set  @strTmp  =  " > ( select   max "
None.gif    
set  @strOrder  =  "  order   by   [ " + @fldName +" ]   asc "
None.gif
end
None.gif
None.gif
set  @strSQL  =  " select   top  "  +   str (@PageSize)  +  "  *   from   [ "
None.gif    + @tblName + "
]   where   [ " + @fldName + " ] +  @strTmp  +  "( [ "
None.gif    + @fldName + "
] from  ( select   top  "  +   str ((@PageIndex - 1 ) * @PageSize)  +  "  [ "
None.gif    + @fldName + "
]   from   [ " + @tblName + " ] +  @strOrder  +  ")  as  tblTmp)"
None.gif    
+  @strOrder
None.gif
None.gif
if  @strWhere  !=   ''
None.gif    
set  @strSQL  =  " select   top  "  +   str (@PageSize)  +  "  *   from   [ "
None.gif        + @tblName + "
]   where   [ " + @fldName + " ] +  @strTmp  +  "( [ "
None.gif        + @fldName + "
] from  ( select   top  "  +   str ((@PageIndex - 1 ) * @PageSize)  +  "  [ "
None.gif        + @fldName + "
]   from   [ " + @tblName + " ]   where  "  +  @strWhere  +  " "
None.gif        
+  @strOrder  +  ")  as  tblTmp)  and  "  +  @strWhere  +  " "  +  @strOrder
None.gif
None.gif
if  @PageIndex  =   1
None.gif
begin
None.gif    
set  @strTmp  =  ""
None.gif    
if  @strWhere  !=   ''
None.gif        
set  @strTmp  =  "  where  "  +  @strWhere
None.gif
None.gif    
set  @strSQL  =  " select   top  "  +   str (@PageSize)  +  "  *   from   [ "
None.gif        + @tblName + "
] +  @strTmp  +  " "  +  @strOrder
None.gif
end
None.gif
None.gif
if  @IsCount  !=   0
None.gif    
set  @strSQL  =  " select   count ( * as  Total  from   [ " + @tblName + " ] "
None.gif
None.gif
exec  (@strSQL)
None.gif
None.gif
GO
None.gif
None.gif


修改后,便于使用的代码:


None.gif 修改一点点便于其他人使用 
None.gif
CREATE   PROCEDURE  GetRecordFromPage 
None.gif@tblName 
varchar ( 255 ),  --  表名 
None.gif
@fldName  varchar ( 255 ),  --  字段名 
None.gif
@OrderfldName  varchar ( 255 ),  --  排序字段名 
None.gif
@StatfldName  varchar ( 255 ),  --  统计字段名 
None.gif
@PageSize  int   =   10 --  页尺寸 
None.gif
@PageIndex  int   =   1 --  页码 
None.gif
@IsCount  bit   =   0 --  返回记录总数, 非 0 值则返回 
None.gif
@OrderType  bit   =   0 --  设置排序类型, 非 0 值则降序 
None.gif
@strWhere  varchar ( 1000 =   ''   --  查询条件 (注意: 不要加 where) 
None.gif
AS  
None.gif
None.gif
declare  @strSQL  varchar ( 6000 --  主语句 
None.gif
declare  @strTmp  varchar ( 100 --  临时变量 
None.gif
declare  @strOrder  varchar ( 400 --  排序类型 
None.gif

None.gif
if  @OrderType  !=   0  
None.gif
begin  
None.gif
set  @strTmp  =  " < ( select   min
None.gif
set  @strOrder  =  "  order   by   [ " + @OrderfldName +" ]   desc
None.gif
end  
None.gif
else  
None.gif
begin  
None.gif
set  @strTmp  =  " > ( select   max
None.gif
set  @strOrder  =  "  order   by   [ " + @OrderfldName +" ]   asc
None.gif
end  
None.gif
None.gif
set  @strSQL  =  " select   top  "  +   str (@PageSize)  +  " "  +  @fldName  +  "  from   [
None.gif+ @tblName + "
]   where   [ " + @OrderfldName + " ] +  @strTmp  +  "( [
None.gif+ @OrderfldName + "
] from  ( select   top  "  +   str ((@PageIndex - 1 ) * @PageSize)  +  "  [
None.gif+ @OrderfldName + "
]   from   [ " + @tblName + " ] +  @strOrder  +  ")  as  tblTmp)" 
None.gif
+  @strOrder 
None.gif
None.gif
if  @strWhere  !=   ''  
None.gif
set  @strSQL  =  " select   top  "  +   str (@PageSize)  +  " "  +  @fldName  +  "  from   [
None.gif+ @tblName + "
]   where   [ " + @OrderfldName + " ] +  @strTmp  +  "( [
None.gif+ @OrderfldName + "
] from  ( select   top  "  +   str ((@PageIndex - 1 ) * @PageSize)  +  "  [
None.gif+ @OrderfldName + "
]   from   [ " + @tblName + " ]   where  "  +  @strWhere  +  " " 
None.gif
+  @strOrder  +  ")  as  tblTmp)  and  "  +  @strWhere  +  " "  +  @strOrder 
None.gif
None.gif
if  @PageIndex  =   1  
None.gif
begin  
None.gif
set  @strTmp  =  "" 
None.gif
if  @strWhere  !=   ''  
None.gif
set  @strTmp  =  "  where  "  +  @strWhere 
None.gif
None.gif
set  @strSQL  =  " select   top  "  +   str (@PageSize)  +  " "  +  @fldName  +  "  from   [
None.gif+ @tblName + "
] +  @strTmp  +  " "  +  @strOrder 
None.gif
end  
None.gif
None.gif
if  @IsCount  !=   0  
None.gif
set  @strSQL  =  " select   count ("  +  @StatfldName  +  ")  as  Total  from   [ " + @tblName + " ]
None.gif
None.gif
exec  (@strSQL) 
None.gif
None.gif
GO  
None.gif


说明:
增加了下面两个部分,其他人拷贝去可根据自己需要进行设定。
@OrderfldName varchar(255), -- 排序字段名
@StatfldName varchar(255), -- 统计字段名

fldName作用由排序转变为控制需要打开的字段。
@fldName varchar(255), -- 字段名

----------------------------------------------
个人测试结果:
通过测试,性能并没有原帖子所说的好。但这可能是机器原因,要知道,在SQL Server中, 2千万条空记录大约要占用3G左右的空间,而 插入这2千万条记录,在我的测试平台上耗费了 近10个小时,内存占用从125M增长到350M左右。我实际测试了一下,在建立索引的情况下,执行一次根据主键,返回一条记录的查询,在512M内存,2.2G CPU,20G单分区存储数据库文件,100M局域网的配置情况下,平均大约需要15s左右(这只是我的个人测试,不具有任何实质性意义。)。

另外我发现,对于上述配置的机器,运行SQL Server时,在百万级别以下的表中执行查询--(索引良好,没有坏点,或者最新索引),速度差别不大,但达到8位数以上,也就是千万以上时候,SQL Server表现就不太好了,当然,这与机器配置有很大关系了。但无可否认,SQL Server  2000还不是企业级数据库的最佳选择,在Oracle执行类似的查询,性能要好于SQL Server。插入执行完毕的时间是4个小时,内存占用一直没有变化:400M。执行相同查询,需要的时间是10s左右。

小弟最近忙于一个公积金项目,对于部门数据库、中央数据库的调度进行了一些评估,Oracle软件+SUN/HP的硬件仍然占了中国政府机构服务器的大部分市场,再就是IBM,占据了高端和甚高端的大部分业务。

微软在这方面打个胜仗,还有很长的路要走--个人认为,和硬件公司合作研发相配套硬件是不二法门。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值