Für Informationen in den folgenden Beispielen besteht big_table
aus Millionen von Zeilen und small_table
von Hunderten.wo like und Reihenfolge von auf verschiedenen Tabellen/Spalten
Hier ist die grundlegende Abfrage ich zu tun bin versucht:
SELECT b.id
FROM big_table b
LEFT JOIN small_table s
ON b.small_id=s.id
WHERE s.name like 'something%'
ORDER BY b.name
LIMIT 10, 10;
Dies ist langsam und ich kann verstehen, warum beiden Indices nicht verwendet werden können.
Meine ursprüngliche Idee war, die Abfrage in Teile zu teilen.
Das ist schnell:
SELECT id FROM small_table WHERE name like 'something%';
Dies ist auch schnell:
SELECT id FROM big_table WHERE small_id IN (1, 2) ORDER BY name LIMIT 10, 10;
Aber zusammen, es wird langsam:
SELECT id FROM big_table
WHERE small_id
IN (
SELECT id
FROM small_table WHERE name like 'something%'
)
ORDER BY name
LIMIT 10, 10;
Es sei denn, die Unterabfrage neu bewertet wird Für jede Zeile sollte es nicht langsamer sein, als beide Abfragen getrennt auszuführen, richtig?
Ich suche nach Hilfe bei der Optimierung der ersten Abfrage und Verständnis, warum die zweite nicht funktioniert.
ERKLÄREN Ergebnis für die letzte Abfrage:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
| 1 | PRIMARY | small_table | range | PRIMARY, ix_small_name | ix_small_name | 768 | NULL | 1 | Using where; Using index; Using temporary; Using filesort |
| 1 | PRIMARY | big_table | ref | ix_join_foreign_key | ix_join_foreign_key | 9 | small_table.id | 11870 | |
temporäre Lösung:
SELECT id FROM big_table ignore index(ix_join_foreign_key)
WHERE small_id
IN (
SELECT id
FROM small_table ignore index(PRIMARY)
WHERE name like 'something%'
)
ORDER BY name
LIMIT 10, 10;
(Folge & erklären ist das gleiche mit einem statt IN VORHANDEN)
ERKLÄREN Ausgang wird:
| 1 | PRIMARY | big_table | index | NULL | ix_big_name | 768 | NULL | 20 | |
| 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 8 | func | 1 | |
| 2 | MATERIALIZED | small_table | range | ix_small_name | ix_small_name | 768 | NULL | 1 | Using where; Using index |
wenn jemand eine bessere Lösung hat, ich bin immer noch interessiert.
Wie sieht der Ausführungsplan für die letzte Abfrage aus? – MaxU
ist 'ix_small_name' ein Index basierend auf' big_table.small_id'? – MaxU
ON b.small_ids.id? und deine Tische, wie sind sie? – e4c5