ich eine Abfrage renne dieüber einen Index in MySQL JOIN mit OR-Bedingung
SELECT parent.field, child.field
FROM parent
JOIN child ON (child.id = parent.id
OR child.id = parent.otherid)
wie folgt aussieht Dies ist jedoch sehr langsam (ca. 100k Aufzeichnungen, und schließt sich mit anderen Tabellen in der realen Version), aber trotz der versuchten Indizes auf
parent.id (PRIMARY),
parent.otherid,
child.id (PRIMARY),
and a composite index of parent.id and parent.otherid
Ich kann MySQL nicht zu einem dieser Indizes bei der Herstellung dieser beitreten zu bekommen.
Ich habe gelesen, dass MySQL nur einen Index pro Join verwenden kann, aber nirgendwo finden kann, ob es einen zusammengesetzten Index verwenden kann, wenn ein JOIN eine OR-Bedingung enthält.
Kann hier jemand wissen, ob es möglich ist, diese Abfrage auf einen Index zu verweisen? Wenn ja, wie?
meine Lösung
(SO läßt mich nicht meine eigene Frage unter atm antworten)
Ein Bündel von Zwicken und kam mit einer ziemlich anständigen Lösung auf, die die Fähigkeit und JOIN behält Aggregieren Sie andere Tabellen.
SELECT parent.field, child.field
FROM parent
JOIN (
SELECT parent.id as parentid,
# Prevents the need to union
IF(NOT ISNULL(parent.otherid) AND parent.otherid <> parent.id,
parent.otherid,
parent.id) as getdataforid
FROM parent
WHERE (condition)
) as foundrecords
ON foundrecords.parentid = parent.id
JOIN child ON child.id = parent.getdataforid
Für Geschwindigkeit erfordert eine Bedingung innerhalb der Unterabfrage die Anzahl der Datensätze in einer temporären Tabelle platziert zu reduzieren, aber ich habe Tonnen von zusätzlichen schließt sich auf der äußeren Abfrage, einige mit dem Kind verbinden und einige der Mutter (mit einigen Aggregaten), so hat dieses für mich am besten funktioniert.
In vielen Fällen wird eine Union schneller und effektiver, aber da ich auf Eltern filtern, aber zusätzliche Daten von Kind (Eltern Selbstreferenzen) wollen, verursachte die Vereinigung zusätzliche Zeilen für mich, die ich nicht konnte konsolidieren. Es ist möglich, dass das gleiche Ergebnis gefunden werden kann, indem man sich mit sich selbst verbindet und eine Where-Bedingung in der äußeren Abfrage aliasiert, aber dieses funktioniert ganz gut für mich.
Dank Jirka für die UNION ALL-Vorschlag ist es, was mich dazu veranlasst, hier zu bekommen :)
Haben Sie laufen 'erklären wählen ...' auf der Abfrage? –
Yep, das Erklären ist, was mich wissen lässt, dass es keine Indizes für diesen Join verwendet. –