Wählen Sie die übergeordnete Zeile nur aus, wenn keine untergeordneten Zeilen vorhanden sind

9

Ich habe eine MySQL-Datenbank, in der Tabelle A eine Eins-zu-viele-Beziehung zu Tabelle B hat, und ich möchte alle Zeilen in Tabelle B auswählen, die in Tabelle A keine Kinder haben. Ich habe versucht,

%Vor%

und

%Vor%

Beide scheinen langsam. Gibt es eine schnellere Abfrage, um dasselbe zu erreichen?

Falls dies relevant ist, hat Tabelle A in meiner Datenbanktabelle etwa 500.000 Zeilen und Tabelle B hat etwa 3 bis 4 Millionen Zeilen.

Bearbeiten: Für die tatsächlichen Tabellen in meiner Datenbank gibt mir explain:

%Vor%

für

%Vor%

und

%Vor%

für

%Vor%

wo in meinem Fall frontend_form471 ist Tabelle A und SchoolData ist Tabelle B

Edit2: In der Tabelle B (SchoolData) in meiner Datenbank ist id der erste Teil eines zweiteiligen Primärschlüssels, daher wird er indiziert und es gibt immer noch mehrere Einträge in B mit derselben ID .

    
murgatroid99 19.07.2011, 19:14
quelle

7 Antworten

8
%Vor%

Sie können dies tun. der äußere Join sollte etwas Leistung bringen, aber nicht viel.

neue Datenbanksysteme werden wahrscheinlich Ihre Abfrage sowieso optimieren, so dass es keinen Unterschied geben wird.

Der richtige Weg hier ist Caching! versuchen Sie, wenn möglich, den Query-Cacher und das Caching auf Anwendungsebene.

natürlich brauchen Sie richtige Indizes.

und mit richtig meine ich auf beiden Tabellen und vorzugsweise einen Hash-Index, da es im Vergleich zu jedem Baum, der logarithmisch ist

, statische Nachschlagzeit hat

Versuchen Sie, vor der Abfrage ein EXPLAIN zu setzen, um zu sehen, was dies wirklich verlangsamt.

Wenn Sie das wirklich schnell brauchen, können Sie Ihre Datenstruktur wiederherstellen.

Sie könnten möglicherweise einen Trigger erstellen, um ein Flag in Tabelle A zu markieren, wenn in der Tabelle ein entsprechender Eintrag vorhanden ist. Natürlich ist diese ID Datenredundanz, aber manchmal ist es es wert. Denken Sie einfach daran, es zu cachen.

ein letzter Gedanke: Sie könnten versuchen, SELECT id FROM A WHERE id NOT IN (SELECT id FROM B) es kann ein wenig schneller sein, da keine tatsächliche Verbindung notwendig ist, aber es kann auch langsamer sein, da die Suche in der Menge von wird eine vollständige Überprüfung sein. Ich bin nicht wirklich sicher, wie das verarbeitet wird, aber es kann einen Versuch wert sein.

    
The Surrican 19.07.2011, 19:18
quelle
1

Es wird langsam sein, egal wie du es siehst. Worst-Case-Leistung wird eine vollständige Kreuzung bei der Schaffung von 2 Billionen potenziellen Übereinstimmungen (4 Mio. * 500k) sein.

Der zweite wird wahrscheinlich schneller ausgeführt, da es sich um eine einzelne Abfrage handelt.

    
Marc B 19.07.2011 19:18
quelle
1

Ihre Indizierung ist schlecht.

Für alle Formen (EXISTS, IN, LINKER JOIN) sollten Sie Indizes für die ID in beiden -Tabellen

haben     
gbn 19.07.2011 19:22
quelle
1

Sie könnten es versuchen

%Vor%

aber ich weiß nicht, ob das schneller geht. Ich hätte zuerst den linken Join versucht. Ich denke, Ihr Problem hat mehr mit Indizes zu tun. Haben Sie Indizes für beide ID-Felder?

    
David Steele 19.07.2011 19:19
quelle
0

Achten Sie darauf, einen Index für A.id und einen weiteren für B.id zu haben.

Was ein bisschen merkwürdig erscheint, ist, dass Sie sich A.id mit B.id anschließen. Ist B.id der Fremdschlüssel zu A oder ist es der Primärschlüssel von B?

    
phlogratos 19.07.2011 19:21
quelle
0

Wenn Ihr Schema etwa so lautet:

%Vor%

Wenn Sie alle Zeilen von Tabelle A, die in Tabelle A nicht untergeordnet sind, haben möchten, versuchen Sie Folgendes nicht:

%Vor%

Ich habe nicht getestet, aber ich denke, dass es schwärzer ist. Denken Sie daran, einen Index über die ID

zu setzen

Hoffe, das hilft

    
wezzy 19.07.2011 19:27
quelle
0

Warum nicht einen leeren Wert anstelle von NULL versuchen? In SQL ist der NULL-Wert niemals wahr im Vergleich zu einem anderen Wert, auch NULL. Ein Ausdruck, der NULL enthält, erzeugt immer einen NULL-Wert, sofern in der Dokumentation für die am Ausdruck beteiligten Operatoren und Funktionen nichts anderes angegeben ist.

    
mustafa 19.07.2011 19:27
quelle

Tags und Links