/ / MySql Query bardzo wolno - mysql, sql, optymalizacja zapytań

Zapytanie MySql bardzo wolno - mysql, sql, query-optimization

W mojej bazie danych uruchamiam następujące zapytanie:

SELECT e.id_dernier_fichier
FROM Enfants e JOIN FichiersEnfants f
ON e.id_dernier_fichier = f.id_fichier_enfant

I zapytanie działa poprawnie. Jeśli zmodyfikuję zapytanie w ten sposób:

SELECT e.codega
FROM Enfants e JOIN FichiersEnfants f
ON e.id_dernier_fichier = f.id_fichier_enfant

Zapytanie staje się bardzo wolne! Problem polega na tym, że chcę wybrać wiele kolumn w tabeli e i f, a zapytanie może potrwać do 1 minuty! Próbowałem różnych modyfikacji, ale nic nie działa. Mam indeksy na id_ * także na e.codega. Enfants ma 9000 linii, a FichiersEnfants ma 20000 linii. Jakieś sugestie ?

Oto pytane informacje (przepraszam, że nie pokazałem ich od początku):

Tabela FichiersEnfants Tabela Enfants Indeks Enfants Wyjaśnij zapytanie 1 Wyjaśnij zapytanie 2

Odpowiedzi:

2 dla odpowiedzi № 1

Różnica w wydajności jest możliwie spowodowany e.id_dernier_fichier będąc w indeksie używanym do JOIN, ale e.codega nie być w który indeks.

Bez pełnej definicji obu tabel i wszystkich ich indeksów nie można tego stwierdzić z całą pewnością. Pomogłoby także włączenie dwóch PLANÓW WYJAŚNIENIA dla dwóch zapytań.


Na razie jednak mogę rozwinąć kilka rzeczy ...

Jeśli INDEKS jest klastrowany (dotyczy to również KLUCZÓW PODSTAWOWYCH), dane są faktycznie przechowywane fizycznie w kolejności INDEKSU. Oznacza to, że wiedząc, że chcesz pozycja x w INDEKSIE także znaczenie oznacza, że ​​chcesz pozycja x na stole.

Jeśli INDEKS nie jest klastrowany, INDEKS po prostu zapewnia dla ciebie wyszukiwanie. Skutecznie mówiąc pozycja x w INDEKSIE odpowiada pozycja y na stole.

Ważne jest tutaj, gdy nie uzyskuje się dostępu do pólokreślone w INDEKSIE. Oznacza to, że musisz faktycznie przejść do TABELI, aby uzyskać dane. W przypadku klastrowanego indeksu „już tam jesteś, narzut związany ze znalezieniem tego pola jest dość niski. Jeśli indeks nie jest klastrowany, musisz jednak skutecznie ŁĄCZYĆ TABELĘ do INDEKSU, a następnie znajdź pole, które „jestem zainteresowany.


Uwaga; Po włączeniu indeksu złożonego (id_dernier_fichier, codega) różni się bardzo od posiadania tylko jednego indeksu (id_dernier_fichier) i osobny indeks na just (codega).


W przypadku twojego zapytania nie sądzę, że musisz w ogóle zmieniać kod. Ale ty może skorzystaj ze zmiany indeksów.

Wspominasz, że chcesz uzyskać dostęp wiele pola. Umieszczenie wszystkich tych pól w indeksie złożonym nie jest prawdopodobnie najlepszym rozwiązaniem. Zamiast tego możesz chcieć utworzyć klastrowany indeks (id_dernier_fichier). Oznacza to, że po znalezieniu * id_dernier_fichier * znajdziesz się już we właściwym miejscu, aby uzyskać wszystkie pozostałe pola.


EDYTOWAĆ Uwaga dotycząca MySQL i INDEKSÓW KLASTEROWANYCH

13.2.10.1. Indeksy klastrowe i pomocnicze

Każda tabela InnoDB ma specjalny indeks nazywany indeksem klastrowym, w którym przechowywane są dane dla wierszy:

  • Jeśli zdefiniujesz KLUCZ PODSTAWOWY w tabeli, InnoDB użyje go jako indeksu klastrowego.
  • Jeśli nie zdefiniujesz KLUCZA PODSTAWOWEGO dla swojej tabeli, MySQL wybiera pierwszy indeks UNIQUE, który ma tylko kolumny NIE NULL jako klucz podstawowy, a InnoDB używa go jako indeksu klastrowego.
  • Jeśli stół nie ma KLUCZA PODSTAWOWEGO lub odpowiedniegoUNIQUE index, InnoDB wewnętrznie generuje ukryty indeks klastrowy w kolumnie syntetycznej zawierającej wartości identyfikatorów wierszy. Wiersze są uporządkowane według identyfikatora, który InnoDB przypisuje wierszom w takiej tabeli. Identyfikator wiersza to 6-bajtowe pole, które rośnie monotonicznie w miarę wstawiania nowych wierszy. W ten sposób wiersze uporządkowane według identyfikatora wiersza są fizycznie uporządkowane w kolejności reklamowej.