Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Korrekte Indizierung bei Verwendung des OR-Operators

Sie missverstehen, wie Indizes funktionieren.

Denken Sie an ein Telefonbuch (das Äquivalent zu einem zweispaltigen Index mit dem Nachnamen zuerst, dem Vornamen zuletzt). Wenn ich Sie bitte, alle Personen im Telefonbuch zu finden, deren Nachname "Smith" ist, können Sie davon profitieren, dass die Namen so geordnet sind; Sie können davon ausgehen, dass die Smiths zusammen organisiert sind. Aber wenn ich Sie bitte, alle Personen zu finden, deren Vorname "John" ist, haben Sie keinen Nutzen aus dem Index. Johns kann jeden Nachnamen haben, und so sind sie über das ganze Buch verstreut, und Sie müssen am Ende auf die harte Tour von vorne bis hinten suchen.

Wenn ich Sie nun bitte, alle Personen zu finden, deren Nachname "Smith" ODER deren Vorname "John" ist, können Sie die Smiths wie zuvor leicht finden, aber das hilft Ihnen überhaupt nicht, die Johns zu finden. Sie sind immer noch im ganzen Buch verstreut und Sie müssen sie auf die harte Tour suchen.

Dasselbe gilt für mehrspaltige Indizes in SQL. Der Index wird nach der ersten Spalte sortiert, dann bei Gleichstand in der ersten Spalte nach der zweiten Spalte, dann bei Gleichstand in den ersten beiden Spalten nach der dritten Spalte usw. Er wird nicht nach allen Spalten sortiert gleichzeitig. Ihr mehrspaltiger Index trägt also nicht dazu bei, Ihre Suchbegriffe effizienter zu gestalten, außer für die Spalte ganz links im Index.

Zurück zu Ihrer ursprünglichen Frage.

Erstellen Sie für jede Spalte einen separaten, einspaltigen Index. Einer dieser Indizes ist eine bessere Wahl als die anderen, basierend auf MySQLs Schätzung, wie viele E/A-Vorgänge der Index fällt an, wenn er verwendet wird.

Moderne Versionen von MySQL verfügen auch über einige intelligente Funktionen zum Zusammenführen von Indexen , also kann die Abfrage Verwenden Sie mehr als einen Index in einer bestimmten Tabelle und versuchen Sie dann, die Ergebnisse zusammenzuführen. Andernfalls ist MySQL in der Regel darauf beschränkt, einen Index pro Tabelle in einer bestimmten Abfrage zu verwenden.

Ein weiterer Trick, den viele Leute erfolgreich anwenden, besteht darin, eine separate Abfrage für jede Ihrer indizierten Spalten durchzuführen (die den jeweiligen Index verwenden sollte) und dann UNION die Ergebnisse.

SELECT fields FROM table WHERE field1='something' 
UNION
SELECT fields FROM table WHERE field2='something' 
UNION
SELECT fields FROM table WHERE field3='something' 
UNION
SELECT fields FROM table WHERE field4='something' 

Eine letzte Bemerkung:Wenn Sie nach demselben 'something' suchen über vier Felder hinweg, sollten Sie noch einmal darüber nachdenken, ob alle vier Felder tatsächlich dasselbe sind, und Sie schuldig sind, eine Tabelle entworfen zu haben, die verstößt gegen die Erste Normalform mit sich wiederholenden Gruppen . Wenn ja, gehören Feld1 bis Feld4 vielleicht in eine einzelne Spalte in einer untergeordneten Tabelle. Dann wird es viel einfacher zu indizieren und abzufragen:

SELECT fields from table INNER JOIN child_table ON table.pk = child_table.fk
WHERE child_table.field = 'something'