[搜片神器]服务器SQL2005查询分页语句你理解了么
在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查询分页语句你理解了么的更多相关文章
- Sql Server系列:查询分页语句
1 利用临时表分页 分页存储过程: CREATE PROCEDURE [USP_Product_GetPaged] ), ), @PageIndex INT, @PageSize INT AS BEG ...
- 跨服务器查询sql语句样例
若2个数据库在同一台机器上:insert into DataBase_A..Table1(col1,col2,col3----)select col11,col22,col33-- from Data ...
- 分页用到的子查询sql语句
说明(2017-8-31 23:30:22): 1. 分页用到的子查询sql语句 select * from(select *,ROW_NUMBER() over(order by id)as num ...
- 跨服务器查询sql语句样例(转)
若2个数据库在同一台机器上: insert into DataBase_A..Table1(col1,col2,col3----) select col11,col22,col33-- from Da ...
- Oracle、MySQL和SqlServe分页查询的语句区别
★先来定义分页语句将要用到的几个参数: int currentPage ; //当前页 int pageRecord ; //每页显示记录数 以之前的ADDRESSBOOK数据表为例(每页显示10条记 ...
- 查询分页的几种Sql写法
查询分页的几种Sql写法 摘自:http://www.cnblogs.com/zcttxs/archive/2012/04/01/2429151.html 1.创建测试环境,(插入100万条数据大概耗 ...
- [C#搜片神器] 之P2P中DHT网络爬虫原理
继续接着上一篇写:使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)[搜片神器] 昨天由于开源的时候没有注意运行环境,直接没有考虑下载BT种子文件时生成子文件夹,可能导致有的朋友运行 ...
- [搜片神器]之DHT网络爬虫的代码实现方法
继续接着第一篇写:使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)[搜片神器] 谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器: http://www.sosobta. ...
- [搜片神器]之DHT网络爬虫的C++程序初步开源
回应大家的要求,特地整理了一开始自己整合的代码,这样最简单,最直接的可以分析流程,至于文章里面提供的程序界面更多,需要大家自己开发. 谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器: ht ...
随机推荐
- [CAMCOCO][C#]我的系统架构.服务器端.(二)----DATA层
这一层在园子里有很多很多的介绍了,这层写好之后老胡也没多研究,基本上就是参考的园子里大咖们的写法,具体的说明老胡也细说不了了,把接口和思路简单描述一下就好,如果有问题还是那句话,感谢您不吝赐教,老胡这 ...
- C# 图片截图(圆形)
//要截图的图片 Image img = Image.FromFile("D:\\soure.jpg"); //截图画板 Bitmap bm = , ); Graphics g = ...
- Windows删除大文件
Temp是目录 或者是 文件很大很大很大很大 cmd rd /s /q Temp
- MVC 增加手机站
首先在全局路由(RouteConfig)中加入以下图片中的代码.
- .Net 接连 Oracle 数据库(Winform)
之前一直是使用Asp.Net 连接 Oracle 10g,最近想写个小程序,所以选择了 Winform.折腾半天后,才发现 Winform 与 Asp.Net 连接 Oracle 是有些许区别的. 区 ...
- QT 多线程程序设计【转】
QT通过三种形式提供了对线程的支持.它们分别是,一.平台无关的线程类,二.线程安全的事件投递,三.跨线程的信号-槽连接.这使得开发轻巧的多线程Qt程序更为容易,并能充分利用多处理器机器的优势.多线程编 ...
- (转)[转]大数据时代的 9 大Key-Value存储数据库
在过去的十年中,计算世界已经改变.现在不仅在大公司,甚至一些小公司也积累了TB量级的数据.各种规模的组织开始有了处理大数据的需求,而目前关系型数据库在可缩放方面几乎已经达到极限. 一个解决方案是使用键 ...
- ThinkPHP控制器
ThinkPHP控制器Controller 1.什么是控制器 在MVC框架中,其核心就是C(Controller)控制器.主要用于接收用户请求,处理业务逻辑. 2.控制器的定义 在一个ThinkPHP ...
- tar 「解/壓」 包
1.tar: short read tar壓縮包文件發生了損壞,或者说不完整. 最近,在寫下載程序的時候,發生了這個問題.初步猜測文件寫完沒有關閉,沒有寫完.
- Excel中 设置使得每行的颜色不一样
在编写测试案例的时候,众多的excel行看的眼睛花花的,这里给出一个小技巧,设置Excel的每行显示的颜色不一样,最终的效果如下: 具体操作: 1. Ctrl+A全选所有表格区域 ...