ユースケースについて多くの詳細を提供していないため、いくつかのヒントを提供しようとします。
「大量のデータ」は、SQL バックエンドから取得した可能性があることを示唆しています。'SELECT DISTINCT...' または 'SELECT ... GROUP BY BRANCH_ID' (または SQL バックエンドに応じて同様の構文) を使用すると、目的の結果が簡単かつ迅速に得られます。確認してください。詳細をお知らせします。
他の人が言ったように、単純な「クローン」は機能しません。最も単純な (そしておそらくより迅速な) 解決策は、データに対する WRT の数が通常少数であると仮定すると、データセットの外部にインデックスを作成することです。元のデータを本当にフィルタリングしたい場合は、データにステータス フィールド (ブール値など) を追加し、最初に出現したものにフラグ (「True」など) を付けます。
PseudoCode: (仮定しましょう: ClientDataSet は cds1 で、cds1 にはステータス フィールド cds1Status (boolean) があります - これはオプションであり、cds1 をソート/フィルター/検索する場合にのみ必要です。TStringList である lIndex があります)
lIndex.Clear;
lIndex.Sorted:=True;
with cds1 do
try
DisableControls;
First;
while not Eof do //scan the dataset
begin
cVal:=cds1Branch_ID.AsString;
Edit; //we anyway update the Status field
if lIndex.Find(cVal, nDummy) then //nDummy - we don't use it.
begin //already in index
cds1Status.AsBoolean:=False; //we say here "No, isn't the 1st occurence"
end
else
begin //Not found! - Well, let's add it...
lIndex.Append(cVal); //update the index
cds1Status.AsBoolean:=True; //mark the first occurence
end;
Post; //save the changes in the status field
Next;
end; //scan
finally
EnableControls; //housekeeping
end;
//警告!- テストされていません。頭で書いたのですが、お分かりいただけたかと思います...
...何を達成しようとしているのか (これは、私たちと共有できる最善のことです) と、BRANCH_ID でどのような選択性を持っているかによって、ステータス エンジンはおそらくまったく必要ありません。そのフィールドの選択性が非常に低い場合 (選択性 = 一意の値の数 / レコードの数)、元の CD の各レコードを入れるよりも、新しいデータセットを作成して一意の値のみをそこにコピーする方がはるかに高速です。編集 + 投稿状態。(データセットの状態を変更することはコストのかかる操作です。特に、CD がリモート データ ストレージ (つまりサーバー) にリンクされている場合)。
h番目、
PS: 私のソリューションは、ほとんどが単純であることを意図しています。また、lIndex.Sorted:=False でテストし、Find の代わりに lIndex.IndexOf を使用することもできます。いくつかの(まれな)ケースでは、より良いです。あなたのデータに依存します。物事を複雑にしたい場合、速度が本当に問題になる場合は、本格的な BTree インデックスを実装して検索を行うことができます (利用可能なライブラリ)。また、CDS のインデックス エンジンを使用して BRANCH_ID のインデックスを作成し、クローンに対して多くの「検索」を実行できますが、選択性が明らかに 1 未満であるため、CD のインデックス全体をスキャンすることは理論的には一意のインデックスをスキャンするより遅くなるはずです。カスタムメイドのインデックスは、データ型、構造、分布などに合わせて調整されます。
my2cだけ