ADOQuery1和ADOQuery2两个数据集结构完成一样(均只有三个字段),主键为字段Ryid,每个库均有2000个以上记录,两个数据集中数据有99%是一样的。现要求一个最高效率的算法:比较两个数据集中的记录,如果ADOQuery2中的记录ADOQuery1中没有,则把这条记录添加至ADOQuery1中。
我用传统的算法:
var
ls_ryid:string;
i:Integer;
begin
ADOQuery1.First;
ADOQuery2.First;
while Not ADOQuery1.Eof do
begin
ls_ryid:=ADOQuery1.FieldbyName('Ryid').AsString;
if Not ADOQuery2.Loacte(Ryid,ls_ryid,[]) then
ADOQuery2.Append;
for i:=0 to ADOQuery2.Fields.Count-1 do
ADOQuery2.Fields[i].value:=ADOQuery1.Field[i].value;
ADOQuery1.Next;
end;
end;
将ADOQuery2、ADOQuery1的CachSzie均设为100;耗时达4分钟。
我用传统的算法:
var
ls_ryid:string;
i:Integer;
begin
ADOQuery1.First;
ADOQuery2.First;
while Not ADOQuery1.Eof do
begin
ls_ryid:=ADOQuery1.FieldbyName('Ryid').AsString;
if Not ADOQuery2.Loacte(Ryid,ls_ryid,[]) then
ADOQuery2.Append;
for i:=0 to ADOQuery2.Fields.Count-1 do
ADOQuery2.Fields[i].value:=ADOQuery1.Field[i].value;
ADOQuery1.Next;
end;
end;
将ADOQuery2、ADOQuery1的CachSzie均设为100;耗时达4分钟。
ls_ryid:string;
i:Integer;
begin
ADOQuery1.First;
ADOQuery2.First;
while Not ADOQuery1.Eof do
begin
ls_ryid:=ADOQuery1.FieldbyName('Ryid').AsString;
if Not ADOQuery2.Loacte(Ryid,ls_ryid,[]) then
begin
ADOQuery2.Append;
for i:=0 to ADOQuery2.Fields.Count-1 do
ADOQuery2.Fields[i].value:=ADOQuery1.Field[i].value;
end;
ADOQuery1.Next;
end;
end;
将ADOQuery2、ADOQuery1的CachSzie均设为100;耗时达4分钟。
有了思路就很好做了。
思路如下:
你的思路是一个表每移动一条,另一个表就要从头到尾查一遍(用的locate函数),
这样的话查询的条数为两个表条数的乘积。
而我的思路是:两个表同时移动。
方法:先将两个表按主键和其他两个字段排序,必须都为升序或降序;然后两个表分别指向第一条记录,如果主键相等,则判断另外的字段是否相等,如果相等则同时移向下一条记录,如果不等则判断那条小,然后另外一个表向下移动,如此一直判断下去。效率要高的多。我已经在PB里实现过了,效率提高好多倍。
b.field2 not in (select a.field2 from a) or b.field3 not in (select a.field3 from a)';
不是就得到所有该插入的纪录了吗,想干什么都行
用SQL肯定高效,但ADOQuery1的数据来源于表, ADOQuery2的数据是用LoadFromFile从文件中获得,不太好用SQL实现。