2016-06-08 2 views
1

Ich habe eine Abfrage wie folgt aus:Wie sollte ich den Index erstellen, wenn OR zwischen den Bedingungen liegt?

DELETE FROM events WHERE type = 4 AND author_id IN (?, ?) AND post_id IN (?, ?) 

Wie Sie wissen, übersetzt author_id IN (? , ?)-author_id = ? OR author_id = ?. Also sollte ich einen Index auf author_id Spalte erstellen?

In der Tat versuche ich zu verstehen, wie MySQL mit Bedingungen behandelt, wenn es OR zwischen ihnen gibt. Ich habe diesen Satz irgendwo gelesen:

MySQL scheint Indizes zu ignorieren, sobald es auf OR trifft.

Aber ich kann die Bedeutung davon nicht verstehen. Kann jemand? Insgesamt, welche Indizes brauche ich für obige Abfrage?

+0

Ersetzen Sie 'DELETE' mit' SELECT type, author_id, post_id', dann 'EXPLAIN' voran und führen Sie die Abfrage mit einem MySQL-Client aus. Erstellen Sie beliebige Indizes, und die EXPLAIN-Abfrage teilt Ihnen mit, welche Indizes verwendet werden. Lesen Sie mehr über die Bedeutung der [EXPLAIN-Ausgabe] (http://dev.mysql.com/doc/refman/5.7/en/explain-output.html). – axiac

+0

Grundlegende Faustregel: Fügen Sie einen Index zu einem Feld hinzu, das in einem 'Entscheidungs'-Kontext verwendet wird, also' Wo', 'Join',' Reihenfolge nach, 'usw. –

+0

@MarcB Nun, manchmal müssen wir ein Vielfaches hinzufügen Spaltenindex. Bsp .: '(type, author_id, post_id)' .. Aber das ist wahr, wenn zwischen diesen Bedingungen 'UND' steht. Ich möchte wissen, wie ich tun soll, wenn es "ODER" zwischen ihnen gibt ... –

Antwort

2

Es stimmt, dass OR normalerweise die effektive Verwendung von Indizes verhindert. Eine Abfrage kann bei der Verarbeitung der WHERE-Klausel im Allgemeinen nur einen Index pro Tabelle verwenden. Wenn Sie also eine Bedingung wie

WHERE col1 = 1 OR col2 = 2 

haben, kann kein einzelner Index verwendet werden, um alle übereinstimmenden Zeilen zu finden. Sie sind in der Regel am besten aus der Abfrage in zwei aufgeteilt und mit UNION:

SELECT ... 
FROM TABLE 
WHERE col1 = 1 
UNION 
SELECT ... 
FROM TABLE 
WHERE col2 = 2 

Aber ich denke, ich irgendwo gelesen, dass in einfachen Fällen MySQL in der Lage ist, diese Umwandlung automatisch durchzuführen. Überprüfen Sie die EXPLAIN Ausgabe für Ihre Abfrage.

Aber wenn die Bedingung OR die gleiche Spalte beinhaltet, kann sie immer noch den Index verwenden, z.B. wenn Sie

WHERE col1 = 1 OR col1 = 2 

haben es hat gerade diese zwei Indexeinträge im Index für col1 nachzuschlagen. Und das ist, was es tut, wenn Sie schreiben:

WHERE col1 IN (1, 2) 

jedoch Ihre Frage ist komplexer als das, weil es auch mehrere Bedingungen mit AND kombiniert wird. Wenn Sie nur = Vergleiche verwenden, könnte dies mit einem mehrspaltigen Index, z.B.

INDEX (type, author_id, post_id) 

Aber wenn Sie mehr IN Bedingungen haben, kann dies nicht geschehen, weil es alle Kombinationen aufzuzählen müßte.

type = 4 AND author_id IN (1, 2) AND post_id IN (10, 20) 

erfordern würde, alle diese Indizes aufzublicken:

4, 1, 10 
4, 1, 20 
4, 2, 10 
4, 2, 20 

Ich glaube nicht, MySQL alle die Kombination wie diese erzeugen (aber ich könnte falsch sein - prüfen Sie die EXPLAIN Ausgabe zu sehen, ob es kann).

Stattdessen wählt es den Index aus, der seiner Meinung nach am effektivsten ist. Verwenden Sie das, um die Zeilen zu finden, die diesem Teil der Bedingung entsprechen, und scannen Sie diese Zeilen, um die verbleibenden Bedingungen zu bewerten.

+0

Große Erklärungen, upvote ..! Schließlich ist jeder Index für meine Abfrage nicht nützlich? –

+0

Ich denke, meine Erklärung war nicht so toll, wenn Sie das fragen müssen. Es wird einen der Indizes auswählen und diesen verwenden und die Zeilen nach den anderen Bedingungen durchsuchen. – Barmar

+0

Ah .. Meinst du nur ein Index wird nützlich sein? Also sollte ich einen getrennten Index für 'type',' author_id', 'post_id' hinzufügen und lassen Sie sich von MySQL entscheiden, welchen Index zu verwenden? –

Verwandte Themen