标题:请教一个问题,需要比较2个表中不同的记录,表过大怎么处理呢?
只看楼主
hjlali
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2008-12-23
得分:0 
以下是引用mywisdom88在2021-8-20 12:24:33的发言:


你表有多少字段,是不是电脑原因,换电脑看看,同时,只用少量字段来测试,看是不是,时间少了。

SELECT ALLTRIM(lxfs) lxfs from ys1 where lxfs NOT in  (select ALLTRIM(lxfs) lxfs from fs1 )


不是电脑的问题,我电脑配置不算差,I7-8550的cpu,好像跟函数有关系,用了alltrim函数后速度大打折扣。

喜欢VFP,就要学懂弄通!
2021-08-20 13:31
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
示例

程序代码:
CREATE CURSOR ys1 (lxfs C(10))
INSERT INTO ys1 VALUES ("1001")
INSERT INTO ys1 VALUES ("1002")
INSERT INTO ys1 VALUES ("1003")
INSERT INTO ys1 VALUES ("1004")
CREATE CURSOR fs1 (lxfs C(10))
INSERT INTO fs1 VALUES ("1001")
INSERT INTO fs1 VALUES ("1003")
INSERT INTO fs1 VALUES ("1005")
INSERT INTO fs1 VALUES ("1006")

SELECT ys1
INDEX on lxfs TAG tag_ys1
SELECT fs1
INDEX on lxfs TAG tag_fs1

? "ys1 NOT IN fs1"
SELECT ys1
SET RELATION TO lxfs INTO "fs1"
LIST FOR !FOUND("fs1")
SET RELATION TO

? "fs1 NOT IN ys1"
SELECT fs1
SET RELATION TO lxfs INTO "ys1"
LIST FOR !FOUND("ys1")
SET RELATION TO
2021-08-20 14:51
xuminxz
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:40
帖 子:749
专家分:2475
注 册:2011-5-8
得分:0 
先复制一个全的,用delete in (sele ...from   )试试。或者用
SELECT ys1.*,fs1.lxfs as lxfsb from ys1 left join fs1 on ys1.lxfs=fs1.lxfs into table tb1
dele for isnull(lxfsb)

[此贴子已经被作者于2021-8-20 17:04编辑过]


dBase有人接盘了。
2021-08-20 16:59
hjlali
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2008-12-23
得分:0 
以下是引用xuminxz在2021-8-20 16:59:30的发言:

先复制一个全的,用delete in (sele ...from   )试试。或者用
SELECT ys1.*,fs1.lxfs as lxfsb from ys1 left join fs1 on ys1.lxfs=fs1.lxfs into table tb1
dele for isnull(lxfsb)

好像不能用join,join的原理有点不适合这个场景,在VFP里join出来的结果很多重复结果。

喜欢VFP,就要学懂弄通!
2021-08-20 19:04
hjlali
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2008-12-23
得分:0 
以下是引用吹水佬在2021-8-20 14:51:06的发言:

示例

CREATE CURSOR ys1 (lxfs C(10))
INSERT INTO ys1 VALUES ("1001")
INSERT INTO ys1 VALUES ("1002")
INSERT INTO ys1 VALUES ("1003")
INSERT INTO ys1 VALUES ("1004")
CREATE CURSOR fs1 (lxfs C(10))
INSERT INTO fs1 VALUES ("1001")
INSERT INTO fs1 VALUES ("1003")
INSERT INTO fs1 VALUES ("1005")
INSERT INTO fs1 VALUES ("1006")

SELECT ys1
INDEX on lxfs TAG tag_ys1
SELECT fs1
INDEX on lxfs TAG tag_fs1

? "ys1 NOT IN fs1"
SELECT ys1
SET RELATION TO lxfs INTO "fs1"
LIST FOR !FOUND("fs1")
SET RELATION TO

? "fs1 NOT IN ys1"
SELECT fs1
SET RELATION TO lxfs INTO "ys1"
LIST FOR !FOUND("ys1")
SET RELATION TO

谢谢你,你这个方法看起来更高阶一点。目前来看,我原来的语句语法是没有问题的,按照2楼的办法,分两段执行也就几秒钟就可以出来结果。
经过比较,主要是用了alltrim函数拖慢了速度,如果能有一条命令快速出结果的办法当然更好了。



[此贴子已经被作者于2021-8-20 19:08编辑过]


喜欢VFP,就要学懂弄通!
2021-08-20 19:06
hjlali
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2008-12-23
得分:0 
以下是引用xuminxz在2021-8-20 16:59:30的发言:

先复制一个全的,用delete in (sele ...from   )试试。或者用
SELECT ys1.*,fs1.lxfs as lxfsb from ys1 left join fs1 on ys1.lxfs=fs1.lxfs into table tb1
dele for isnull(lxfsb)

2楼的办法可以,出结果几秒钟。

喜欢VFP,就要学懂弄通!
2021-08-20 19:10
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用hjlali在2021-8-20 19:06:21的发言:


谢谢你,你这个方法看起来更高阶一点。目前来看,我原来的语句语法是没有问题的,按照2楼的办法,分两段执行也就几秒钟就可以出来结果。
经过比较,主要是用了alltrim函数拖慢了速度,如果能有一条命令快速出结果的办法当然更好了。

对比测试一下,30W条记录
程序代码:
** 测试数据
CREATE CURSOR ys1 (lxfs C(10))
FOR i=1 TO 300000
    INSERT INTO ys1 VALUES (PADL(i,7,"0"))
ENDFOR
CREATE CURSOR fs1 (lxfs C(10))
APPEND FROM DBF("ys1")
SELECT ys1
GO TOP 
REPLACE lxfs WITH "ys1_000001"
GO BOTTOM 
REPLACE lxfs WITH "ys1_100000"

t = SECONDS()
SELECT ALLTRIM(lxfs) AS MY_KEY from fs1 DIST NOCO INTO TABLE TEMP_KEY
SELECT * FROM ys1 where ALLTRIM(lxfs) NOT in(SELECT MY_KEY FROM TEMP_KEY) NOWAIT   
?SECONDS()-t && 5.5s

** 去掉ALLTRIM
t = SECONDS()
SELECT lxfs AS MY_KEY from fs1 DIST NOCO INTO TABLE TEMP_KEY
SELECT * FROM ys1 where lxfs NOT in(SELECT MY_KEY FROM TEMP_KEY) NOWAIT   
?SECONDS()-t && 5.0s

t = SECONDS()
SELECT fs1
INDEX on lxfs TAG tag_fs1
SELECT ys1
SET RELATION TO lxfs INTO "fs1"
COPY TO tmp FOR !FOUND("fs1")
SET RELATION TO
?SECONDS()-t && 3.5s
SELECT * FROM tmp NOWAIT 
2021-08-20 20:38
hjlali
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2008-12-23
得分:0 
以下是引用mywisdom88在2021-8-20 12:24:33的发言:


你表有多少字段,是不是电脑原因,换电脑看看,同时,只用少量字段来测试,看是不是,时间少了。

SELECT ALLTRIM(lxfs) lxfs from ys1 where lxfs NOT in  (select ALLTRIM(lxfs) lxfs from fs1 )


根据经验,是子句不能包含alltrim()函数,否则执行非常慢,会卡死

喜欢VFP,就要学懂弄通!
2021-08-20 20:41
hjlali
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2008-12-23
得分:0 
以下是引用吹水佬在2021-8-20 20:38:17的发言:


对比测试一下,30W条记录
** 测试数据
CREATE CURSOR ys1 (lxfs C(10))
FOR i=1 TO 300000
    INSERT INTO ys1 VALUES (PADL(i,7,"0"))
ENDFOR
CREATE CURSOR fs1 (lxfs C(10))
APPEND FROM DBF("ys1")
SELECT ys1
GO TOP
REPLACE lxfs WITH "ys1_000001"
GO BOTTOM
REPLACE lxfs WITH "ys1_100000"

t = SECONDS()
SELECT ALLTRIM(lxfs) AS MY_KEY from fs1 DIST NOCO INTO TABLE TEMP_KEY
SELECT * FROM ys1 where ALLTRIM(lxfs) NOT in(SELECT MY_KEY FROM TEMP_KEY) NOWAIT   
?SECONDS()-t && 5.5s

** 去掉ALLTRIM
t = SECONDS()
SELECT lxfs AS MY_KEY from fs1 DIST NOCO INTO TABLE TEMP_KEY
SELECT * FROM ys1 where lxfs NOT in(SELECT MY_KEY FROM TEMP_KEY) NOWAIT   
?SECONDS()-t && 5.0s

t = SECONDS()
SELECT fs1
INDEX on lxfs TAG tag_fs1
SELECT ys1
SET RELATION TO lxfs INTO "fs1"
COPY TO tmp FOR !FOUND("fs1")
SET RELATION TO
?SECONDS()-t && 3.5s
SELECT * FROM tmp NOWAIT

谢谢你的专业指导!!确实不是数据量的问题,是语法有问题,where in()括号里面的子句不能包含alltrim,否则执行不下去。我不知道你用的什么数据测试的,我把对比数据脱敏了,你实测下看看。希望还有人能给出更多的方案!
对比数据.rar (2.08 MB)


[此贴子已经被作者于2021-8-20 21:21编辑过]


喜欢VFP,就要学懂弄通!
2021-08-20 21:01
hjlali
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2008-12-23
得分:0 
以下是引用sdta在2021-8-20 13:09:35的发言:

用数据说话

数据已上传,已脱敏,可以试试看。

对比数据.rar (2.08 MB)

喜欢VFP,就要学懂弄通!
2021-08-20 21:03



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




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

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