• 主页
  • API 调用
  • 基础类
  • 控件与界面
  • 数据库相关
  • DataWindow
  • 项目管理
  • Web 应用
  • 脚本语言

大数据量查询,进度条 解决方案

wzh2021 2013-05-25 10:14:00
p_phonecall的表结构很简单,就5列。但是这个表的数据量很大,有6千万--1亿条记录左右!!
billing_nbr--手机号
ny--所属月份
cell_id--小区编号
js-计数(全部为1)
duration--通话时长(单位秒)

现在每次到了select的时候 程序就假死了
怎么解决啊
谢谢大家了,很着急啊 !

代码如下:
for ll_i=1 to dw_phoneno_oftelphone.rowcount() //手机号码

ls_phoneno = dw_phoneno_oftelphone.object.phoneno[ll_i]

for ll_j=1 to dw_xq.rowcount() //小区编号
yield()
//进度条
if isValid(w_prostep) then w_prostep.f_step() //
w_prostep.SetRedraw(TRUE)

ll_xqid = dw_xq.object.id[ll_j]
ls_xqbh = dw_xq.object.xqbh[ll_j]
ls_xqmc = dw_xq.object.xqmc[ll_j]
//查询某月、某手机号、在某小区的通话次数
SELECT sum(js) into :ll_hz_count FROM p_phonecall
WHERE ( p_phonecall.billing_nbr = :ls_phoneno) AND ( p_phonecall.ny = :ls_ny ) and (cell_id=:ls_xqbh) ;
if isnull(ll_hz_count) then ll_hz_count=0

IF ib_cancel = TRUE THEN goto rett

next
//查询某月、某手机号的通话次数总和
SELECT sum(js) into :ll_all_count FROM p_phonecall
WHERE ( p_phonecall.billing_nbr = :ls_phoneno) AND ( p_phonecall.ny = :ls_ny ) ;
if isnull(ll_all_count) then ll_all_count=0

next

...全文
735 点赞 收藏 16
写回复
16 条回复
wxliangzyt 2013年11月04日
引用 2 楼 lzp_lrp 的回复:
首先执行一次 SELECT sum(js) into :ll_all_count FROM p_phonecall WHERE ( p_phonecall.billing_nbr = :ls_phoneno) AND ( p_phonecall.ny = :ls_ny ) ; 把变量换成值,然后单独执行一下sql,看一下需要多长时间,如果在10秒以上,需要建立索引,如果只是在几秒,应该还可以接爱,再看一下你的循环,执行多少次,如果执行在几十次以上,建议你不要用sql写了,用个数据窗口,一次把要查询的数据全查出来,然后用find进行查找,这样速度就快了
同意
回复 点赞
marongc 2013年09月05日
我觉得多线程的可以的 其实搞个动画,只要让用户知道程序还在运行就可以了
回复 点赞
DavinciTeam 2013年09月03日
兄弟,能帮我解决哈这个问题吗?在线等待求助:http://bbs.csdn.net/topics/390576946
回复 点赞
yingmu 2013年06月09日
哦,对不起,没问题了,还是没领会楼主的意思,原来是遍历每个小区的值,明白了。
回复 点赞
yingmu 2013年06月09日
引用 10 楼 wzh502887976 的回复:
...... 使用了多线程控制进度条,主程序也不会假死了 谢谢大家
那楼主是使用怎样的规则来显示进度条的当前进度值的呢?例如过了一秒钟,和过了十秒钟,进度条分别要行进到百分之多少,这个是根据什么来定的?如果是一个数据窗口对象,还可以在retrieverow事件里写代码来根据行数显示百分比(当然,会拖累dw的效率),你这个只是相当于从服务器得到一个值而已啊。
回复 点赞
I_am_Z 2013年06月08日
行,挺厉害的,还真有用多线程搞进度条的,赞一个。
回复 点赞
wzh2021 2013年06月08日
都不管用的 你们想的 我都试过了 都会卡死的 每个月都有6000万条数据左右,占用空间2-3个G 我现在每个月建了一个表,并且建立了索引, xxxx_yyyymm格式的表名 所有的查询通过存储过程实现了:建立临时表,对临时表创建索引,再进行count或者sum,快多了 使用了多线程控制进度条,主程序也不会假死了 谢谢大家
回复 点赞
yingmu 2013年06月06日
晕,没看题目,光看回复了,原来你只是想求总记录数啊?用count就行了呗,sum干什么?sum肯定是比count慢啊。再就是对数据库进行优化,特别是按照你可能的查询条件建几个索引试试。
回复 点赞
yingmu 2013年06月06日
嗯,有两种方案,看你是不是确实需要一次把这么大的一批数据一次查出来。如果确实需要,又不想让别人以为程序死掉了,那把数据窗口在retrievestart时setredraw(false),retrieveend时再setredraw(true),同时在start时timer启动一个定时器,在界面上搞个动画出来,在end时把定时器关掉,动画去掉。如果想显示进度条,只能在retrieverow事件中写代码,但在这里面写任何代码(估计包括注释也是),都会影响retrieve执行的效率。如果不一定是需要一次显示出来(例如,仅是为了显示,而不用于查询后接着打印),你可以一次retrieve多少条,然后记录一个锚点,当翻到本次的最后一条时,再从锚点retrieve(当然,需要在retrievestart中return 2),这样相同于从多次retrieve,就是类似于以前用asp开发网页,要分页显示很多数据一个道理,速度应该会快很多。不过如果是要一次就要查出来用(打印了,批量干什么了),这种办法就不行了。
回复 点赞
老知了-米芾 2013年06月06日
嗯,版主 正解。 还有PB代码里 dwcontrol.rowcount() 单独弄个变量,先求值在循环。
回复 点赞
WorldMobile 2013年05月25日
首先执行一次 SELECT sum(js) into :ll_all_count FROM p_phonecall WHERE ( p_phonecall.billing_nbr = :ls_phoneno) AND ( p_phonecall.ny = :ls_ny ) ; 把变量换成值,然后单独执行一下sql,看一下需要多长时间,如果在10秒以上,需要建立索引,如果只是在几秒,应该还可以接爱,再看一下你的循环,执行多少次,如果执行在几十次以上,建议你不要用sql写了,用个数据窗口,一次把要查询的数据全查出来,然后用find进行查找,这样速度就快了
回复 点赞
阿木已被某人占用 2013年05月25日
根据查询条件建索引
回复 点赞
WorldMobile 2013年05月25日
不是,把你需要的数据汇总出来,你不是要查哪个小区吗?按小区来进行分组,只检索你需要的小区
回复 点赞
wzh2021 2013年05月25日
引用 4 楼 lzp_lrp 的回复:
用的是什么数据库? 是否可以想办法优化一下 如果要一分钟,建议用数据窗口把一次把需要的数据处理出来,不要用sql,然后再用find来查找相应的行来处理,速度要快很多
几千万条 dw出来?
回复 点赞
WorldMobile 2013年05月25日
用的是什么数据库? 是否可以想办法优化一下 如果要一分钟,建议用数据窗口把一次把需要的数据处理出来,不要用sql,然后再用find来查找相应的行来处理,速度要快很多
回复 点赞
wzh2021 2013年05月25日
引用 2 楼 lzp_lrp 的回复:
首先执行一次 SELECT sum(js) into :ll_all_count FROM p_phonecall WHERE ( p_phonecall.billing_nbr = :ls_phoneno) AND ( p_phonecall.ny = :ls_ny ) ; 把变量换成值,然后单独执行一下sql,看一下需要多长时间,如果在10秒以上,需要建立索引,如果只是在几秒,应该还可以接爱,再看一下你的循环,执行多少次,如果执行在几十次以上,建议你不要用sql写了,用个数据窗口,一次把要查询的数据全查出来,然后用find进行查找,这样速度就快了
1分钟左右
回复 点赞
发动态
发帖子
PowerBuilder
创建于2007-09-28

599

社区成员

6.6w+

社区内容

PowerBuilder 相关问题讨论
社区公告
暂无公告