标题:千万级数据查询问题
只看楼主
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
嘿嘿

授人以渔,不授人以鱼。
2015-07-16 16:19
taifu945
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:80
帖 子:1545
专家分:3298
注 册:2012-7-6
得分:0 
以下是引用blackjack076在2015-7-16 16:09:25的发言:

对的,确实是这样,我也试过用这语句运行,但是运行时间过去十几分钟,进度条未动呢,所以放弃了。
这两条命令不会比你上面那段代码更慢吧?
2015-07-16 16:22
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
精简一下代码:
程序代码:
SET DELETED OFF
USE a.dbf ALIAS aa IN 0
USE b.dbf ALIAS bb IN 0
SELECT aa
RECALL ALL 
INDEX ON num TAG num
SELECT bb
RECALL ALL 
SET RELATION TO num INTO "aa"
SCAN
    IF FOUND("aa")
        DELETE IN "bb"
        DELETE IN "aa"
    ENDIF
ENDSCAN
SET RELATION TO
BROWSE
SELECT aa
BROWSE
2015-07-16 16:23
kiff
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:贵宾
威 望:46
帖 子:756
专家分:2531
注 册:2013-1-30
得分:3 
以下是引用TonyDeng在2015-7-16 15:29:08的发言:

实际上,这是程序设计的问题。需求分析的时候,本来已经可以明确处理办法:既然数据规模可预期是这个数量级,那么在后期再这样批量处理必然是低效的,无论什么算法,都不及在用户界面做删除动作的时候,程序立即把所有牵连的数据一并删掉,此时只是查找一笔记录的消耗而已,还不至于留下不同步数据误导应用的隐患。用户界面做动作,CPU空闲时间多的是,到一百个表中各删一笔记录,也比到现在去删十多万高效得多,也不影响用户响应,那个时候即使停顿半秒也比现在坐数分钟可接受得多。
 
处理的办法当然还有许多,化整为零等都可以,一切都应围绕系统整体需求来定,割裂一两个功能模块来做,合併起来就未必是那么回事了。

就是这样,程序设计的问题。
2015-07-16 17:20
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:3 
以下是引用taifu945在2015-7-16 16:22:09的发言:

这两条命令不会比你上面那段代码更慢吧?

你SELECT 语句慢的原因在 WHERE 中,我发现在WHERE 子句中,使用函数的响应时间,比不实用函数的时间要长很多,
我最近,在VFP上更新SQL2000表的时候,发现,

SELECT 表1  &&已经按编号做了索引的
SCAN
  BH=LTRIM(编号)
  XM=姓名
  SQL_STR='UPDATE SQL_TAB SET XM=?XM WHERE LTRIM(BH)=?BH
  SQLEXEC(句柄,SQL_STR)
ENDSCAN

上面的实用时间,比下面的长很多

SELECT 表1  &&已经按编号做了索引的
SCAN
  BH=LTRIM(编号)
  XM=姓名
  SQL_STR='UPDATE SQL_TAB SET XM=?XM WHERE BH=?BH
  SQLEXEC(句柄,SQL_STR)
ENDSCAN

不知道,各位高手,是不是也知道这个?
但我在SET XM=?XM,中,加函数,影响的时间,不多,SET XM=?XM

[ 本帖最后由 mywisdom88 于 2015-7-16 17:34 编辑 ]
2015-07-16 17:24
kiff
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:贵宾
威 望:46
帖 子:756
专家分:2531
注 册:2013-1-30
得分:0 
用RECALL ALL也不合理,软件使用过程中删除了的记录,凭什么要把它恢复。
2015-07-16 17:25
沙枣
Rank: 4
来 自:宁夏银川
等 级:业余侠客
威 望:5
帖 子:103
专家分:221
注 册:2015-5-31
得分:3 
回复 楼主 blackjack076
以下的代码只须对排序库扫描一遍,就可以挑出A、B库全部共有的记录(包括多条重复),可以大大减少磁盘访问次数。


close all
set talk off
set safe off
? time()    &&运程开始时间

sele 1
use A
append from B
sort to C on num
*这一步可能比较慢
use C
do while .not.eof()
p1=alltrim(num)
if .not.eof()
skip
endif
do while .not.eof()
aa=alltrim(num)
if p1=aa
skip-1
delete
skip
delete
else
exit
endif
if .not.eof()
skip
endif
enddo
enddo
pack
*C库剩下的就是未比中的记录
close all
set talk on
set safe on
? time()    &&运行结束时间
---------------------------------

[ 本帖最后由 沙枣 于 2015-7-16 17:47 编辑 ]
2015-07-16 17:45
taifu945
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:80
帖 子:1545
专家分:3298
注 册:2012-7-6
得分:0 
以下是引用mywisdom88在2015-7-16 17:24:18的发言:

 
你SELECT 语句慢的原因在 WHERE 中,我发现在WHERE 子句中,使用函数的响应时间,比不实用函数的时间要长很多,
我最近,在VFP上更新SQL2000表的时候,发现,
 
SELECT 表1  &&已经按编号做了索引的
SCAN
  BH=LTRIM(编号)
  XM=姓名
  SQL_STR='UPDATE SQL_TAB SET XM=?XM WHERE LTRIM(BH)=?BH
  SQLEXEC(句柄,SQL_STR)
ENDSCAN
 
上面的实用时间,比下面的长很多
 
SELECT 表1  &&已经按编号做了索引的
SCAN
  BH=LTRIM(编号)
  XM=姓名
  SQL_STR='UPDATE SQL_TAB SET XM=?XM WHERE BH=?BH
  SQLEXEC(句柄,SQL_STR)
ENDSCAN
 
不知道,各位高手,是不是也知道这个?
但我在SET XM=?XM,中,加函数,影响的时间,不多,SET XM=?XM


那是因为他用的是C型字段,必须考虑到可能有的尾部空格。如果改用V型字段,完全可以不用这个函数。
2015-07-16 21:58
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
V型字段?我还没用过,你意思是在SQL2000上用V型字段?可以不担心空格问题?
2015-07-17 10:22
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:3 
上传数据,纸上谈兵是没用的。

坚守VFP最后的阵地
2015-07-17 11:03



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-455451-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024468 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved