【发布时间】:2020-08-21 12:33:45
【问题描述】:
我在 VFP9 中(是的,我知道)下一个查询运行良好,但是使用大小为 20mb(或 9k 行)的 DBF(表)在游标上创建一个大于 2gb 的临时文件(并且这会使 VFP9 因 32 位而崩溃)
SELECT DISTINCT t1.*;
FROM t1,t2;
WHERE ALLTRIM(t1.name) = ALLTRIM(t2.name);
AND ALLTRIM(t1.name2) = ALLTRIM(t2.name2);
AND t1.tyc = t2.tyc;
AND t1.nc = t2.nc;
AND t1.forced = 0;
AND t1.secuence NOT in (Select secuence FROM t2);
Into Cursor cursordel
我只放这段代码是因为它有效,除非我有超过 2k 的行 我认为用 join 替换“not in”可以解决问题,但没有奏效,或者至少没有我尝试过的方式......
【问题讨论】:
-
附带说明:您可以通过使用
ALLTRIM更新表中的所有行一次并安装对任何插入或更新的行执行相同操作的触发器来避免查询中的ALLTRIM。 -
查询正在查找所有 t1,其中 t2 中的 tyc、nc 和名称匹配,但 t2 中没有匹配序列。 也许它的真正目的是检查 t2 中是否存在与 tyc、nc 和名称的匹配,但与另一个序列。好吧,也许也许不是。我当然不能知道。如果是这种情况,您只需要一次查找而不是两次。除此之外,请按照 Gordon 的建议使用
EXISTS进行查找并提供他提到的索引。 -
@ThorstenKettner,用 alltrim() 更新所有行将是一个没有意义的操作,除非它是 LTRIM() - 这不太可能。
-
@Cetin Basoz:我不明白为什么这毫无意义。
ALLTRIM删除 FoxPro 中的前导和尾随空格。你为什么要那些名字呢?如果它们总是被触发器立即删除(加上对现有数据的每次更新一次),查询中将不再需要ALLTRIM,甚至可以在这些列上提供有用的索引以便更快地查找。 -
@ThorstenKettner,这毫无意义,因为 OP 在他的问题中说 VFP 和 DBF。虽然,VFP 支持 Varchar(不是真的),但 99.999% 的 DBF 将字符字段作为 Char 字段,而不是 Varchar 字段。这意味着 ALLTRIM() 只是意味着 LTRIM() 并且结果文本仍然与尾随空格相同。 IOW,它不能帮助您删除存储数据中的尾随空格。我相信,OP 对 ALLTRIM() 的使用实际上没有任何目的(可能他想确保有一个完全匹配,他可以简单地使用 == 或设置 ANSI ON)。我不想要名称中的某些内容,我更喜欢使用索引。
标签: sql optimization visual-foxpro