MySql Zeitintensive Kreuzsuche beschleunigen

Sprint

Erfahrenes Mitglied
Hallo zusammen,

wir haben in unserer Firma ein Script laufen, das in einer, momentan ca 2000 Datensätzen großen, Tabelle nach Übereinstimmungen zwischen verschiedenen Datensätzen sucht. Dabei werden mehrere Namen, Adressen und bis zu 15 Telefonnummern und 5 Emailadressen miteinander verglichen. Im Moment wird die Tabelle Satz für Satz durchgegangen, alle nötigen Werte in den übrigen Datensätzen gesucht und das Ergebnis in ein Protokollfeld geschrieben.
Das sind natürlich sehr viele Operationen notwendig und mit den rund 2000 Datensätzen braucht das Script schon gut 20 - 25 Sekunden. Das ist schon jetzt bereits zu lange um das einfach mal so zwischendrin zu starten. Abgesehen davon, daß in Kürze möglicherweise die maximale Scriptlaufzeit erreicht ist.

Nun zu meiner Frage. Gibt es eine optimierte Routine, die sowas schneller erledigt oder evtl. einen Workaround, der sowas ohne Datenbank rein in PHP erledigt und die Datenbank nur am Anfang und am Ende mal anspricht?
 
Ich bin da völlig offen. Es ist nur so, daß ich mit dem normalen Join schon so meine Verständnisprobleme habe. Hier hab ich jetzt über 40 Felder, die miteinander verglichen werden müssen. Und in Kürze kommen noch weitere Namensfelder aus einer weiteren Tabelle dazu.

So sehen die jetzigen Vergleiche innerhalb einer Tabelle aus:

Name und Vorname mit Name und Vorname
PLZ und ORT mit PLZ und Ort
Straße und Hausnummer mit Straße und Hausnummer
Email 1-5 mit Email 1-5
Tel und Landesvorwahl 1-5 mit Tel und Landesvorwahl 1-5 und Fax 1-5 und Mobil 1-5
Fax und Landesvorwahl 1-5 mit Fax und Landesvorwahl 1-5 und Tel 1-5 und Mobil 1-5
Mobil und Landesvorwahl 1-5 mit Mobil und Landesvorwahl 1-5 und Fax 1-5 und Tel 1-5

Das überfordert mich jetzt vollständig. Oder ich bin zu doof dafür. Vielleicht hat es auch noch keiner geschafft, mir das verständlich zu erklären.
 
Sind die Vergleiche AND oder OR verknüpft? Also (Name und Vorname mit Name und Vorname) AND (PLZ und ORT mit PLZ und Ort) AND ... oder (Name und Vorname mit Name und Vorname) OR (PLZ und ORT mit PLZ und Ort) OR ... ? Ich würde mal OR raten. Also hier beispielhaft und ungetestet:

SQL:
SELECT
a.Name as aName,
b.Name as bName,
a.Vorname as aVorname,
b.Vorname as bVorname,
a.PLZ as aPLZ,
b.PLZ as bPLZ,
a.Ort as aOrt,
b.Ort as bOrt,
... usw....
FROM
mytable a
INNER JOIN
mytable b
ON
(
(a.Name = b.Name AND a.Vorname = b.Vorname) OR
(a.PLZ = b.PLZ AND a.Ort = b.Ort) OR
... usw ...
)
 
Zuletzt bearbeitet von einem Moderator:
Hallo zusammen,

hat leider etwas gedauert bis ich mich wieder damit beschäftigen konnte.

@melmager: Die Vergleiche sind dafür da, daß wir jederzeit sofort im Blick haben, welche Kunden in welchen Daten übereinstimmen. Es geht dabei um die Suche nach potentiellen bzw. tatsächlichen Steuersündern. Und da ist es natürlich interessant zu wissen, welche Firmen z.B. die gleiche Telefonnummer oder Email verwenden. Dieses Script läuft normalerweise nachts, kann aber bei Bedarf auch per Hand angestoßen werden.

@BaseBallBatBoy: Das Script funktioniert so, allerdings passen die Ergebnisse leider gar nicht mit den tatsächlichen Ergebnissen zusammen. Ich schätze, ich habe mich bei der Problembeschreibung unklar ausgedrückt. Ich will mal versuchen, das anhand einer kleinen Tabelle zu verdeutlichen

KundeA Name A Tel 123456 Fax 234567
KundeB Name B Tel 741258
KundeC Name C Tel 963258 Fax 123456
KundeD Name A Tel 885522 Fax 998888
KundeE Name E Tel 123456 Fax 121314

So, das ist die Ausgangslage. Nach dem Scriptlauf sollen in den einzelnen Datensätzen die Übereinstimmungen in einem Textfeld gespeichert sein. Die obige Tabelle würde dann also so aussehen:

KundeA Name A Tel 123456 Fax 234567 Tel mit Fax KundeC, Tel mit Tel KundeE
KundeB Name B Tel 741258
KundeC Name C Tel 963258 Fax 123456 Fax mit Tel KundeA
KundeD Name A Tel 885522 Fax 998888
KundeE Name E Tel 123456 Fax 121314 Tel mit Tel KundeA


D.h. es wird ein Datensatz in allen relevanten Feldern komplett mit allen anderen verglichen und nur die Übereinstimmungen in das Textfeld eingetragen. Dann ist der nächste Datensatz dran.
 
Zuletzt bearbeitet:
Dann müsste man in den On zweig nur mit OR arbeiten
kleines Problem dabei: Die Datensätze brauchen eine eindeutige ID nummer zum Filtern sonst geht es nicht.

SQL:
.....
on
(a.tel = b.tel OR a.tel = b.fax or a.fax=b.tel or a.fax=b.fax) 
where 
a.id <> b.id

ohne id haste sonst immer eine übereinstimmung da Kunde A gleich Kunde A ist :)
eventuell muss man mit "left join" arbeiten statt "inner join"
 
Zuletzt bearbeitet:
Nochmal sorry, daß ich mich jetzt erst wieder melde.

Im Prinzip funktioniert das schon und die Ergebnisse mit JOIN werden auch sehr schnell bereitgestellt. Dabei sind natürlich alle Ergebnisse durcheinander und damit kann ich beim Erstellen des Ergebnistextes nichts anfangen. Wenn ich die dann aber sortiert ausgeben lasse, bin ich wieder bei dem gleichen Zeitaufwand wie vorher, da die Sortierung bei momentan knapp über 4 Mio. Ergebnissätzen bereits deutlich über 20 Sekunden dauert. Und dann kommt ja noch die Verarbeitung der Ergebnisse dazu, so daß mir im Endeffekt keine Zeitersparnis bleibt.

Inzwischen möchte ich glauben, daß es da keine gewaltigen Verbesserungsmöglichkeiten gibt. Muß ich halt dabei bleiben und mir für den Fall, daß die Scriptlaufzeit irgendwann Ärger macht, eine Aufteilung einfallen lassen.

Trotzdem vielen Dank an alle, die mir versucht haben zu helfen.
 
Zeig uns doch mal dein gesamtes SQL welches du nun hast. Evtl. lässt sich da noch was machen.
Zudem wären so 10-20 Testdatensätze (aka insert into) auch nicht schlecht, damit man mal damit rumspielen kann. Und wie sieht es eigentlich mit Indizes auf der Tabelle aus? Gibts da bereits was oder brauchst du die gar nicht?
 
Zurück