Moin!
Ich habe eine Frage zur potentiellen Performance und Erfahrungen eurerseits.
Situation:
Ich habe eine unbestimmte Anzahl von Querys, welche jeweils eine ID-Spalte halten. Die Daten sind vorsortiert. Über alle Querys muss ich die ID-Übereinstimmungen finden.
Mit Dem Ergebnis will ich eine
SQL-Abfrage füttern.
Ich könnte einfach alle IDs aus einer Querys nehmen und jeweils einen Abgleich des gewünschten Feldes für diese durchführen. Das könnte aber zu sehr langen
SQL-Strings führen. Entsprechend will ich dort eine Vorverarbeitung durchführen.
Eine Überführung der IDs in int-Arrays erscheint mir von den Arbeitsschritten her eigentlich unnötig.
Ich mache jetzt das:
- Querys auf Beschaffenheit kontrollieren und nur die weiter betrachten, die wichtig sind
- Wenn nur eine
Query übrig bleibt kann ich die IDs dieser einfach verarbeiten
- Wenn mehrere Querys übrig bleiben suche ich mir die längste, um eine übergreifende Schleife zu starten
-- Ich kontrolliere die aktuellen Daten über alle
Query auf Gleichheit
--- bei Erfolg habe ich eine ID gefunden
--- bei Fehlschlag schaue ich mir die IDs aller Querys an und schreite voran, solang die IDs der zu überprüfenden Querys kleiner sind als die der Schleifen-
Query
--- am Ende schreite ich einen Datensatz in der Schleifen-
Query weiter und die Checks beginnen erneut
Die Tests schauen soweit gut aus. Geht das ganze aber effektiver / schneller?
Delphi-Quellcode:
function func_findPoiIds(sArrIdField : TArray<
String>; quArrData : TArray<TFDQuery>) :
String;
var sIdFieldLong :
String;
quDataLong : TFDQuery;
bQuAction : Boolean;
i, iPos : Integer;
begin
Result := '
0';
if Length(sArrIdField) <> Length(quArrData)
then Exit;
//Start Entfernen leerer Elemente
i := 0;
while i < Length(quArrData)
do
begin
if quArrData[i].IsEmpty
then
begin
Delete(quArrData, i, 1);
Delete(sArrIdField, i, 1);
Dec(i);
end;
Inc(i);
end;
if Length(sArrIdField) <> Length(quArrData)
then Exit;
//Ende Entfernen leerer Elemente
//Start nur ein Element übrig
if Length(quArrData) = 1
then
begin
quArrData[0].First;
while not quArrData[0].Eof
do
begin
Result := Result + '
,' + quArrData[0].FieldByName(sArrIdField[0]).AsString;
quArrData[0].Next;
end;
Exit;
end;
//Ende nur ein Element übrig
//Start Längstes Element finden
iPos := 0;
for i := 1
to Length(quArrData)-1
do
if quArrData[i].RecordCount > quArrData[iPos].RecordCount
then
iPos := i;
sIdFieldLong := sArrIdField[iPos];
Delete(sArrIdField, iPos, 1);
quDataLong := quArrData[iPos];
quDataLong.First;
Delete(quArrData, iPos, 1);
for i := 0
to Length(quArrData)-1
do
quArrData[i].First;
//Ende Längstes Element finden
//Start QueryVergleich
while not quDataLong.Eof
do
begin
//Start ID anfügen und weiter springen
bQuAction := true;
for i := 0
to Length(quArrData)-1
do
if quDataLong.FieldByName(sIdFieldLong).AsInteger <> quArrData[i].FieldByName(sArrIdField[i]).AsInteger
then
begin
bQuAction := false;
Break;
end;
if bQuAction
then
begin
Result := Result + '
,' + quDataLong.FieldByName(sIdFieldLong).AsString;
quDataLong.Next;
for i := 0
to Length(quArrData)-1
do
quArrData[i].Next;
Continue;
end;
//Ende ID anfügen und weiter springen
//Start QuerryData hochsetzen
for i := 0
to Length(quArrData)-1
do
begin
bQuAction := false;
while not quArrData[i].Eof
and (quDataLong.FieldByName(sIdFieldLong).AsInteger > quArrData[i].FieldByName(sArrIdField[i]).AsInteger)
do
begin
quArrData[i].Next;
bQuAction := true;
end;
if bQuAction
then Break;
end;
//nach PositionsVeränderung neue Prüfung einleiten
if bQuAction
then Continue;
//Ende QuerryData hochsetzen
quDataLong.Next;
end;
//Ende QueryVergleich
end;