MySQL: wie index eine "ODER" - Klausel
Ich bin ausführen der folgenden Abfrage,
SELECT COUNT(*)
FROM table
WHERE field1='value' AND (field2 >= 1000 OR field3 >= 2000)
Gibt es einen index über Feld1 und anderen zusammengesetzt, die über field2&feld3.
Sehe ich MySQL wählt immer die field1 index und macht dann eine Verknüpfung mit den beiden anderen Feldern, die ziemlich schlecht ist, denn es muss mitmachen 146.000 Zeilen.
Vorschläge, wie das zu verbessern? Dank
(EDIT NACH DEM VERSUCH, VORGESCHLAGENE LÖSUNG)
Sitz in der vorgeschlagenen Lösung habe ich gesehen, das auf Mysql beim spielen mit diesem.
SELECT COUNT(*) FROM (SELECT * FROM table WHERE columnA = value1
UNION SELECT * FROM table WHERE columnB = value2) AS unionTable;
ist viel langsamer als ausführen:
SELECT COUNT(*)
FROM table
WHERE (columnA = value1 AND columnB = value2)
OR (columnA = value1 AND columnC = value3)
Ist mit zwei Composite-index:
index1 (columnA,columnB)
index2 (columnA,columnC)
Interessant genug ist, dass Sie aufgefordert werden Mysql zu "erklären" der Abfrage-es nimmt immer index1 auf beide Fälle und index2 wird nicht verwendet.
Wenn ich die Indizes ändern:
index1 (columnB,columnA)
index2 (columnC,columnA)
Und die Abfrage:
SELECT COUNT(*)
FROM table
WHERE (columnB = value2 AND columnA = value1)
OR (columnC = value3 AND columnA = value1)
Dann ist es der Schnellste Weg, die ich gefunden habe, arbeitet Mysql.
InformationsquelleAutor JoséMi | 2010-05-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die typische Art und Weise zu brechen
OR
Prädikate mitUNION
.Beachten Sie, dass Ihr Beispiel passt nicht gut mit Ihren Indizes. Auch wenn Sie ausgelassen
field1
aus dem Prädikat, Sie hättenfield2 >= 1000 OR field3 >= 2000
, die kann nicht mit einem index. Wenn Sie Indizes auf(field1, field2)
und(field1,field3)
oderfield2
oderfield3
getrennt, erhalten Sie eine einigermaßen schnelle Abfrage.Beachten Sie, dass Sie haben, um einen alias für die abgeleitete Tabelle, die ist, warum die Unterabfrage den alias
T
.Einem real-world-Beispiel. Spalte und Tabelle Namen wurden anonymisiert!
field2 >= 1000
undfield3 >= 2000
) zweimal. (Hinweis: die Verwendung einer temporären Tabelle ;))UNION UNION DISTINCT standardmäßig. Doppelte Zeilen werden entfernt, da ein Teil der UNION-Konstrukt. Wenn man wirklich auf Sie zählen doppelt, würde man mit 'UNION'. Hast du auch versuchen, die Aussage, die ich vorgeschlagen, auf einige ähnliche Tabelle?
InformationsquelleAutor David M
Ich bin neu hier, also kann ich nicht kommentieren, Beiträge anderer Leute, aber das ist in Bezug auf die Beiträge von David M. und soulmerge.
Die temporäre Tabelle ist nicht notwendig. Die UNION David M. vorgeschlagen, nicht doppelt zählen, wie die UNION impliziert eine deutliche (d.h. wenn eine Zeile vorhanden, in die eine Hälfte der union, ignorieren Sie es in die andere). Wenn du mit UNION ALL, erhalten Sie zwei Datensätze.
http://dev.mysql.com/doc/refman/5.0/en/union.html
InformationsquelleAutor Brandongk