首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

关于SQL2008千万级数据量逐行判断的有关问题

2013-04-26 
关于SQL2008千万级数据量逐行判断的问题有一个表里保存了1000万的公交车数据量,需要逐行对其中4列的值进行

关于SQL2008千万级数据量逐行判断的问题
有一个表里保存了1000万的公交车数据量,需要逐行对其中4列的值进行判断。
具体来说:有卡号,日期,时间,线路;判断规则是,同一个卡号,在用90分钟里,线路值不同的话,认为有一次公交换乘。
我的解决思路是,先把这四个列按照卡号,日期,时间排序取出,并存入临时表里。
再定义八个变量,
--定义循环取值变量
declare @l nchar(20)
declare @x nchar(6)
declare @d nchar(8)
declare @sj nchar(6)

declare @ln nchar(20)
declare @xn nchar(6)
declare @dn nchar(8)
declare @sjn nchar(6)
然后用游标逐行取出相邻的两行值,赋值给这八个变量。
接下来依次判断卡号,日期,时间,线路;
单次判断完成后,执行
set @l=@ln
set @x=@xn
set @d=@dn
set @sj=@sjn
再读取下一行记录,并重复判断
用这样的方法能在4分钟里完成
现在发帖求助,是否有更高效的解决方案。
因为,有看到资料说,数据超过1万行就应避免使用游标,改用while来处理
可是我试了while循环,一个晚上都没出结果。
附上SQL代码
--生成临时表
select  * into #b from 
(
select listbh,[dealrq],[dealsj],xlbh  from cpuxfmx2011701720
union all 
select listbh,[dealrq],[dealsj],xlbh  from cpuxfmx2011721731 

AS table_source  

--定义游标
declare test_Cursor cursor scroll for
select listbh,xlbh,[dealrq], dealsj from #b  order by listbh,[dealrq],dealsj
go

open test_Cursor --打开游标

--定义计数器
declare @c int
set @c=0

--定义变量
declare @l nchar(20)
declare @x nchar(6)
declare @d nchar(8)
--3.27增加判断规则,同一天里刷卡时间间隔小于90分钟
declare @sj nchar(6)

declare @ln nchar(20)
declare @xn nchar(6)
declare @dn nchar(8)
declare @sjn nchar(6)

--取第一行的值
fetch FIRST from test_Cursor into @l,@x,@d,@sj

while @@FETCH_STATUS=0
begin

--逐行取值
fetch NEXT from test_Cursor into @ln,@xn,@dn,@sjn

--判断
if @l=@ln
begin
if @x!=@xn
begin
if @d=@dn
begin
--if datediff(minute, convert(datetime, @sj), convert(datetime, @sjn))<=90
--由于dealsj字段里包含不能转换成datetime的值
--采用下述方式判断,并把间隔改成90+40(时间的60进制与数字的10进制差异)=130
if convert(int,(SUBSTRING(@sjn,1,4)))-convert(int,(SUBSTRING(@sj,1,4)))<=130
begin
--累加计数器
set @c=@c+1
end

end

end

end

 set @l=@ln
 set @x=@xn
 set @d=@dn
 set @sj=@sjn 

end

print @c

--关闭游标
close test_Cursor
--销毁游标
deallocate test_Cursor

--销毁临时表
drop table #b 




 
[解决办法]
换CTE试试,1000万用游标能跑出数据证明你的硬件很强大,或者并发很小,不然早挂了。
[解决办法]

卡号,日期,时间,线路
先合并为 card,datetime,line,再用row_number(over card order by datetime)得到按card分组的序号列o

select a.card,a.datetime,b.datetime
from t a
left join t b on a.card=b.card and a.o=b.o-1
where b.datetime-a.datetime<90分钟 and a.line<>b.line

[解决办法]
看下执行计划,应该能分析出慢所在位置。如果没能应用到索引自然会慢。
[解决办法]
引用:
表的结构
COLUMN_NAME DATA_TYPE 


listbh     nchar     卡号
dealrq     nchar     刷卡日期
dealsj     nchar     刷卡时间
xlbh     nchar     线路编号
id     int       主键
判断规则是,同一个卡号,在用90分钟里,线路编号不同的话,认为有一次公交换乘。

恳请……


CTE可以递归也可以非递归,你在本该非递归的地方用递归来说自然不适合啦。要理解,不能死搬硬套。

热点排行
Bad Request.