Po pierwsze, aby poradzić sobie z konkretnymi pytaniami, które zadajesz:
-
Jak udokumentowano w
CREATE INDEXSkładnia :Dlatego zanim nawet rozważysz
HASHindeksowania, należy mieć świadomość, że jest to tylko dostępne wMEMORYiNDBsilniki pamięci masowej:więc może nawet nie być dla ciebie opcją.Ponadto należy pamiętać, że indeksy w kombinacjach
IDiLookupsam może nie być optymalny, ponieważ TwójWHEREpredykat również filtruje natablea.Elg_IDpart1itableb.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.