A. sql怎么控制检索出的最大数据量,数量太大机器受不了,有能分批检索的命令吗
用分页查询算法来实现。给你一个我写的通用分页存储过程,将这个存储过程创建在你的SQL数据库上,调用该过程即可实现分页查询:
/*
通用存储过程
只要传入页码,每页大小,查询的sql语句,排序方式(不需要order)即可
*/
CREATE Procere [sp_common_cuspage3]
(
@PageNo int, --当前查询页码
@PageSize int, --每页数量
@sql nvarchar(2000), --查询的SQL语句
@order nvarchar(200), --排序方式,例如:ResID desc
@totalcount int out --返回当前查询SQL的符合总条数
)
AS
Begin
declare @querysql nvarchar(2000)
declare @countsql nvarchar(2000)
declare @begin int
declare @end int
declare @totalPage int
--查询符合条件的条目数
set @countsql = N'select @count = count(*) from ('+@sql + N')G0'
exec sp_executesql @countsql, N' @count int output ', @totalcount output
--计算总页码及纠正当前页码
set @totalPage = (@totalcount-1)/@PageSize +1
IF(@PageNo > @totalPage ) set @PageNo = @totalPage
--计算起止位置
set @begin = @PageSize * (@PageNo-1)
set @end = @PageSize * @PageNo +1
--组合出SQL进行查询
set @querysql = N'select * from ('
set @querysql = @querysql + N' SELECT Row_Number() OVER(ORDER BY ' + @order + N' ) as RowID ,G0.* FROM ('
set @querysql = @querysql + @sql
set @querysql = @querysql + N' ) G0 ) G1'
set @querysql = @querysql + N' Where G1.RowID >' + CAST(@begin as nvarchar) + N' AND G1.RowID<'+CAST(@end as nvarchar)
--print @querysql
exec(@querysql)
End
B. 请教各位,如何分批获取数据库中数据
在有些业务场景中需要分批去取数据库表中的全部数据来进行处理,最简单的方法就是使用分页查询语句(偷懒以MySQL为例):
[sql] view plain print?
select * from datatable limit offset,amount
select * from datatable limit offset,amount
这里就会有一个问题,随着offset值的越来越大,这条sql要扫描的表数据就会越来越多,因为要定位到offset这一行就需要扫描比offset小的所有行。显然在一张大数据量的表中,去这样做,性能就会出问题。为了避免这样的情形出现,我们自然会想到使用索引来解决,比如使用自增序列id进行分批取:
[sql] view plain print?
select * from datatable where id >= start and id<start+batchCount
select * from datatable where id >= start and id<start+batchCount
这样我们对id建索引,然后分批去取,显然效果会高很多,但是如果自增序列由于删除等操作变得不是连续,就会出现空执行和多执行的情况出现。要解决这个方法,我们就需要结合使用索引和分页的优势来处理:
[sql] view plain print?
select * from datatable where id >= start limit batchCount
select * from datatable where id >= start limit batchCount
然后每次取回来我们再计算出起始id值,再去取下一批数据。这样就可以既避免了第一种不走索引,查询性能低下的问题,又解决了第二种id不连续,导致取回来的数据量不稳定导致浪费的问题了。
C. sql语句是分批循环查询,定义一个pno,这段代码报错,应该如何修改啊
Stringstr2="";
for(intpno=0;pno<3;pno++){
if(pno==0){
str2="select*from(selectrownumrowa,d.*from(selectssw.sms_id,ssw.phone_numberfromsms_send_waitsswleftjoinsms_send_receivessronssr.sms_id=ssw.sms_idwherenotexists(selectssrb.phone_numberfromsms_send_receive_blacklistssrbwheressrb.phone_number=ssw.phone_number)andssw.send_wait_timebetweensysdate-1andsysdate+1)dwhererownum<=pno*2)whererowa>(pno-1)*2"
}else{
str2=str2+"union"+"select*from(selectrownumrowa,d.*from(selectssw.sms_id,ssw.phone_numberfromsms_send_waitsswleftjoinsms_send_receivessronssr.sms_id=ssw.sms_idwherenotexists(selectssrb.phone_numberfromsms_send_receive_blacklistssrbwheressrb.phone_number=ssw.phone_number)andssw.send_wait_timebetweensysdate-1andsysdate+1)dwhererownum<=pno*2)whererowa>(pno-1)*2"
}
}
pstmt=conn.prepareStatement(str2);
ResultSetrs=pstmt.executeQuery();
//你要是想把sql语句拼起来,一次性执行了,就用上面的方法,要是不想或不会拼,可以把pstmt=conn.prepareStatement(str2);
ResultSetrs=pstmt.executeQuery();
写到for循环里面,每循环一次执行一次,都可以的!
D. sql in语句的性能问题
每个机票订单含有多个票,用符合条件的订单List,去查询对应的票List。
两张表的关联方式是用一个特性的key关联,其中包含,代理商区分标余启喊志,订单号,订单类型等,是一个长度在30~50之间的varchar
遍历list一条一条查的话,IO太多,显然不合适旁档。我们就想到用in来实现批量查询
在beta测试时,库中表里只有一个月的数据,大约在1000万左右,测试时没有发现问题。
到了线上之后,发现查询数据非常慢,两万左右的in条件,查询起来,时间在10分钟左右,显然出现了慢查询。
针对这个问题,做了几个测试,看了下执行计划,如下所示
事实上我们看到,在in语句中数据量不大的情况下,索引是有效的,不过这个数量已经是极限了。
下面是我的语句
这里在in里面包含了三万条数据,索引实效了。
这里我们首先想到,强制使用索引会不会有所帮助如下
但是,事实上并没有效果,这是结果
解下来我们分析一下,两个问题,索引为什么会失效
这个问题需要从两个方面入手
1.索引区竖野分度
2.预计扫描行数
3.优化器的选择
先看第一个,索引的区分度,经过随机采样,看着内容还是很高的。
预计扫描行数
预计扫描行数的话,如前两图所示,基本都走了全表扫描。
优化器的选择
优化器选择时,衡量了回表等操作,综合考虑,这里没有办法继续下去了,只能问到DBA了。
在数据表大时,索引负重较大,同样的情况下,in语句里面数据条数够大时,索引会失效,可以通过force index尝试一下,不过成功的可能行很小,尽量分批去查找,批次数量可配置。
E. SQL项目列表中的列数超过655时,结果查看器无法执行查询怎么解决
那就分批来呀,按他们的主键排列,确保查询出来的顺序是一致的,然后查询你需要显示的列名,剩下的放在第二批查,分别把他们复制粘贴出来就好。
F. (问题解决再追加100分)sql server存储过程实现查询数据条数过大,分页查询怎么实现
按说5-8w这样数量级的数据没有问题,写入Excel是布比较耗性能,主要还是要通过优化写入Excel的代码效率上去考虑。你可以考虑利用分批查询写入的方式来避免一次写太多的数据到Excel:将你的查询结果分段,比方你的语句中能不能用时间来认为分段,每次返回部分结果。
回到你的问题,对大数据量查询的解决方案有以下两种:
(1)、将全部数据先查询到内存中,然后在内存中进行分页,这种方式对内存占用较大,必须限制一次查询的数据量。
(2)、采用存储过程在数据库中进行分页,这种方式对数据库的依赖较大,不同的数据库实现机制不通,并且查询效率不够理想。以上两种方式对用户来说都不够友好。
2.解决思路
通过在待查询的数据库表上增加一个用于查询的自增长字段,然后采用该字段进行分页查询,可以很好地解决这个问题。下面举例说明这种分页查询方案。
(1)、在待查询的表格上增加一个long型的自增长列,取名为“queryId”,mssql、sybase直接支持自增长字段,oracle可以用sequence和trigger来实现。然后在该列上加上一个索引。
添加queryId列的语句如下:
Mssql: [QUERYID] [bigint] IDENTITY (1, 1)
Sybase: QUERYID numeric(19) identity
Oracle:
CREATE SEQUENCE queryId_S
INCREMENT BY 1
START WITH 1
MAXVALUE 999999999999999 MINVALUE 1
CYCLE
CACHE 20
ORDER;
CREATE OR REPLACE TRIGGER queryId_T BEFORE INSERT
ON "test_table"
FOR EACH ROW
BEGIN
select queryId_S.nextval into :new.queryId from al;
END;
(2)、在查询第一页时,先按照大小顺序的倒序查出所有的queryId,
语句如下:select queryId from test_table where + 查询条件 +order by queryId desc 。
因为只是查询queryId字段,即使表格中的数据量很大,该查询也会很快得到结果。然后将得到的queryId保存在应用服务器的一个数组中。
(3)、用户在客户端进行翻页操作时,客户端将待查询的页号作为参数传递给应用服务器,服务器通过页号和queyId数组算出待查询的queyId最大和最小值,然后进行查询。
算出queyId最大和最小值的算法如下,其中page为待查询的页号,pageSize为每页的大小,queryIds为第二步生成的queryId数组:
int startRow = (page - 1) * pageSize
int endRow = page * pageSize - 1;
if (endRow >=queryIds.length)
{
endRow = this.queryIds.length - 1;
}
long startId =queryIds[startRow];
long endId =queryIds[endRow];
查询语句如下:
String sql = "select * from test_table" + 查询条件 + "(queryId <= " + startId + " and queryId >= " + endId + ")";
3.效果评价
该分页查询方法对所有数据库都适用,对应用服务器、数据库服务器、查询客户端的cpu和内存占用都较低,查询速度较快,是一个较为理想的分页查询实现方案。经过测试,查询4百万条数据,可以在3分钟内显示出首页数据,以后每一次翻页操作基本在2秒以内。内存和cpu占用无明显增长。
以上也仅仅是分页查询结果查看的问题,你需要写入到Excel的话还需要考虑Excel写入代码的执行效率,这部分是很值得研究的。
G. sql分批查询
搜第二行的后面两条数据
SELECT * From im_friend WHERE id > '' ORDER BY 'id' ASC LIMIT 0,2
H. sql2008数据库,九百万条数据,如何快速查询
根据你说的需求:
"可程序中需要查询每行的所有数据"、“查询全部九百万条数据”
-------------------------------
这样的需求跟索引没有关系了(因为已经肯定是走全表扫描的了),要提高效率的办法就是:1、提高硬盘的io速度;2、增加内存以使sql server有更多的缓存。
另外,你程序不要一次性取那么多数据返回,这样会拖死的,建议你考虑变换下处理逻辑(如:分批取回--可以根据id列值进行分批;将数据直接在服务端存成文本再传回本地处理)。
"而是需要根据这些数据逐一进行其他功能的操作,这款程序是不联网的"
--------------------------------
就算这样的话,也不能一次性把9百万数据一次性取回,如果你非要取出来再操作的话,那你得考虑分批去取。或者你把处理逻辑写在存储过程,然后由SQL SERVER本身去完成逻辑处理。总之,不管怎样,你也是得优化你现在的处理逻辑(现有处理逻辑我觉得不合理,效率很低下)。
“真正部署到电力网的服务器上速度会不会提高呢”
------------------------
服务器当然比你本地要快得多啦,硬件配置根本就不同一个级别,但不管怎样,还是建议你参考上面的建议优化你的处理逻辑才行,否则,你系统的效率将很低。