Po pierwsze, aby poradzić sobie z konkretnymi pytaniami, które zadajesz:
-
Jak udokumentowano w
CREATE INDEX
Składnia :Dlatego zanim nawet rozważysz
HASH
indeksowania, należy mieć świadomość, że jest to tylko dostępne wMEMORY
iNDB
silniki pamięci masowej:więc może nawet nie być dla ciebie opcją.Ponadto należy pamiętać, że indeksy w kombinacjach
ID
iLookup
sam może nie być optymalny, ponieważ TwójWHERE
predykat również filtruje natablea.Elg_IDpart1
itableb.IDpart1
—możesz również skorzystać z indeksowania tych kolumn. -
Zakładając, że pożądane typy indeksów są obsługiwane przez silnik pamięci masowej, możesz je mieszać według własnego uznania.
-
Możesz użyć wskazówki dotyczącej indeksu aby zmusić MySQL do używania indeksów innych niż te, które w innym przypadku wybrałby optymalizator.
-
Jest zazwyczaj wystarczająco sprytny, ale nie zawsze. W tym przypadku jednak prawdopodobnie ustalił, że liczność indeksów jest taka, że lepiej jest użyć tych, które wybrał.
Teraz, w zależności od używanej wersji MySQL, tabele wyprowadzone z podzapytań mogą nie mieć żadnych indeksów, które można wykorzystać do dalszego przetwarzania:w konsekwencji połączenie z b
może wymagać pełnego skanowania tej tabeli pochodnej (w twoim pytaniu nie ma wystarczających informacji, aby dokładnie określić, jaki to może być problem, ale schema1.tableb
posiadanie 1,5 miliona rekordów sugeruje, że może to być istotny czynnik).
Zobacz Optymalizacja podzapytań aby uzyskać więcej informacji.
Dlatego należy starać się unikać używania tabel pochodnych, jeśli to w ogóle możliwe. W tym przypadku tabela pochodna nie ma żadnego celu, ponieważ można po prostu dołączyć do schema1.tablea
i schema1.tableb
bezpośrednio:
UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND a.ID IS NOT NULL
AND b.IDpart1 IS NOT NULL
AND b.Lookup IS NOT NULL
ORDER BY ID, Lookup
Jedyną utraconą rzeczą jest filtr dla DISTINCT
rekordy, ale zduplikowane rekordy po prostu (próbują) nadpisać zaktualizowane wartości ponownie tymi samymi wartościami — co nie przyniesie efektu, ale może okazać się bardzo kosztowne (zwłaszcza w przypadku tak wielu rekordów w tej tabeli).
Użycie ORDER BY
w tabeli pochodnej było bezcelowe, ponieważ nie można było polegać na osiągnięciu określonej kolejności UPDATE
, podczas gdy w tej poprawionej wersji zapewni, że wszelkie aktualizacje, które zastępują poprzednie, będą miały miejsce w określonej kolejności:ale czy jest to konieczne? Być może można go usunąć i zaoszczędzić na dowolnej operacji sortowania.
Należy sprawdzić predykaty w WHERE
klauzula:czy wszystkie są konieczne (NOT NULL
sprawdza a.ID
i b.Lookup
na przykład są zbędne, biorąc pod uwagę, że każdy taki NULL
rekordy zostaną usunięte przez JOIN
orzeczenie)?
W sumie pozostawia nam to:
UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND b.IDpart1 IS NOT NULL
Dopiero jeśli wydajność jest nadal niezadowalająca, należy dalej przyjrzeć się indeksowaniu. Czy odpowiednie kolumny (tj. te używane w JOIN
i WHERE
predykaty) indeksowane? Czy indeksy są wybierane do użycia przez MySQL (należy pamiętać, że może używać tylko jednego indeks na tabelę dla wyszukiwań:do testowania zarówno JOIN
predykat i predykaty filtrujące:być może potrzebny jest odpowiedni indeks złożony)? Sprawdź plan wykonania zapytania za pomocą EXPLAIN
aby dokładniej zbadać takie problemy.