Mam do czynienia z następującymi problemami i nie jestem pewien, jaka jest najlepsza praktyka.
Rozważ poniższą tabelę (która stanie się duża):
id PK | giver_id FK | odbiorca_id FK | data
Używam InnoDB iz tego, co rozumiem, automatycznie tworzy indeksy dla dwóch kolumn klucza obcego. Jednak będę również wykonywać wiele zapytań, w których muszę dopasować określoną kombinację:
SELECT...WHERE giver_id = x AND recipient_id = t
.
Każda taka kombinacja będzie wyjątkowa w tabeli.
Czy jest jakaś korzyść z dodania dwukolumnowego indeksu do tych kolumn, czy też dwa indywidualne indeksy w teorii byłyby wystarczające / takie same?
Odpowiedzi:
Jeśli masz dwa indeksy jednokolumnowe, w Twoim przykładzie zostanie użyty tylko jeden z nich.
Jeśli masz indeks z dwiema kolumnami, zapytanie może być szybsze (powinieneś zmierzyć). Indeks dwukolumnowy może być również używany jako indeks pojedynczej kolumny, ale tylko dla kolumny wymienionej jako pierwsza.
Czasami warto mieć indeks na (A, B) i inny indeks na (B). To sprawia, że zapytania korzystające z jednej lub obu kolumn są szybkie, ale oczywiście zajmuje również więcej miejsca na dysku.
Wybierając indeksy, należy również wziąć pod uwagę wpływ na wstawianie, usuwanie i aktualizację. Więcej indeksów = wolniejsze aktualizacje.
źródło
Indeks obejmujący, taki jak:
... oznaczałoby, że indeks mógłby zostać użyty w przypadku odniesienia do zapytania
giver_id
lub kombinacjigiver_id
irecipient_id
. Pamiętaj, że kryteria indeksu są oparte na skrajnej lewej stronie - zapytanie odnoszące się tylko dorecipient_id
nie byłoby w stanie użyć indeksu pokrywającego w podanym przeze mnie oświadczeniu.Ponadto MySQL może używać tylko jednego indeksu na SELECT, więc indeks pokrywający byłby najlepszym sposobem optymalizacji zapytań.
źródło
MySQL can only use one index per SELECT
to już nie jest prawdą, byłoby miło, gdybyś zredagował swoją odpowiedź w celu zaktualizowania.recipient_id
?INDEX (col1, col2, col3, col4)
indeks będzie stosowany do wyszukiwań zWHERE
klauzulą taką jakcol1 = 'A'
lubcol1 = 'A' AND col2 = 'B'
lubcol1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'
, ale ten konkretny indeks nie będzie używany do niczego podobnegoWHERE col2 = 'B'
lubWHERE col3 = 'C' AND col4 = 'D'
ponieważ pola wyszukiwania nie są pozostawione najbardziej w definicji indeksu. Będziesz musiał dodać dodatkowe indeksy, aby pokryć te pola.Jeśli jeden z indeksów kluczy obcych jest już bardzo selektywny, mechanizm bazy danych powinien użyć tego indeksu dla określonego zapytania. Większość silników baz danych używa pewnego rodzaju heurystyki, aby wybrać optymalny indeks w takiej sytuacji. Jeśli żaden z indeksów nie jest sam w sobie wysoce selektywny, prawdopodobnie ma sens dodanie indeksu zbudowanego na obu kluczach, ponieważ mówisz, że będziesz często używać tego typu zapytań.
Inną rzeczą do rozważenia jest to, czy możesz wyeliminować pole PK w tej tabeli i zdefiniować indeks klucza podstawowego w polach
giver_id
irecipient_id
. Powiedziałeś, że kombinacja jest wyjątkowa, więc prawdopodobnie zadziała (biorąc pod uwagę wiele innych warunków, na które tylko Ty możesz odpowiedzieć). Zazwyczaj jednak uważam, że dodatkowa złożoność, która dodaje, nie jest warta zachodu.źródło
Inną rzeczą do rozważenia jest to, że charakterystyka wydajności obu podejść będzie oparta na rozmiarze i liczności zbioru danych. Może się okazać, że indeks dwukolumnowy staje się bardziej wydajny tylko przy pewnym progu rozmiaru zestawu danych lub dokładnie odwrotnie. Nic nie zastąpi metryk wydajności dla konkretnego scenariusza.
źródło