MySQL - dlaczego nie indeksować każdego pola?

107

Ostatnio nauczyłem się cudowności indeksów, a wydajność znacznie się poprawiła. Jednak przy wszystkim, czego się nauczyłem, nie mogę znaleźć odpowiedzi na to pytanie.

Indeksy są świetne, ale dlaczego ktoś nie mógł po prostu zindeksować wszystkich pól, aby tabela była niesamowicie szybka? Jestem pewien, że jest dobry powód, aby tego nie robić, ale co powiesz na trzy pola w tabeli trzydziestopolowej? 10 na 30 polu? Gdzie należy wyznaczyć granicę i dlaczego?

Vael Victus
źródło
7
spróbuj wstawić wartość do tabeli z ponad 10 tys. wpisów, która jest zindeksowana, wszystkie wpisy muszą zostać zaktualizowane z powodu wstawiania / usuwania, a to jest ogromne obciążenie czasowe i trochę narzut pamięci, jeśli każda wartość ma indeks
Jesus Ramos
5
Jest jeszcze jeden powód, poza przestrzenią i wydajnością zapisu: używanie wielu indeksów w celu uzyskania dostępu do jednej tabeli jest bardzo nieefektywne . Oznacza to, że nawet jeśli masz jeden indeks w każdej kolumnie, wydajność wybierania nie jest zbyt dobra, jeśli dostęp do wielu kolumn jest uzyskiwany w klauzuli WHERE. W takim przypadku najlepszy jest indeks wielokolumnowy.
Markus Winand
1
jeśli masz tabelę z 30 polami, powinieneś naprawdę przyjrzeć się jej strukturom. Powinny być bardzo trudne w obsłudze.
webs

Odpowiedzi:

122

Indeksy zajmują miejsce w pamięci (RAM); Za dużo lub za dużo indeksów i baza danych będzie musiała wymieniać je na iz dysku. Wydłużają również czas wstawiania i usuwania (każdy indeks musi być aktualizowany dla każdej wstawionej / usuniętej / zaktualizowanej części danych).

Nie masz nieskończonej pamięci. Sprawienie, że wszystkie indeksy mieszczą się w pamięci RAM = dobrze.

Nie masz nieskończonego czasu. Indeksowanie tylko tych kolumn, które chcesz zindeksować, minimalizuje uderzenie wydajności wstawiania / usuwania / aktualizowania.

Brian Roach
źródło
11
Ładna, swobodna odpowiedź, dająca ogólne zrozumienie, ale nie bardzo pomocna w określeniu, gdzie narysować linię indeksów. Skąd możesz wiedzieć? Wystarczy dodać je do powszechnie używanych pól GDZIE i mieć nadzieję na najlepsze?
Andrew,
@Andrew, półtora roku później, czy znalazłeś odpowiedź na swoje pytanie?
Sinjai
1
@Sinjai Dodawanie ich do często używanych kolumn to prawdopodobnie dobra zasada. Ale w przeciwnym razie możesz dużo poczytać, okazuje się, że chcesz zostać ekspertem w zakresie indeksów. na przykład. stackoverflow.com/questions/3049283/…
Andrew
Nie zapomnij o miejscu na dysku.
jpmc26
27

Pamiętaj, że każdy indeks musi być aktualizowany za każdym razem, gdy wiersz jest aktualizowany, wstawiany lub usuwany. Więc im więcej masz indeksów, tym wolniejsza wydajność operacji zapisu.

Ponadto każdy indeks zajmuje więcej miejsca na dysku i pamięci (gdy jest wywoływany), więc może również spowolnić operacje odczytu (w przypadku dużych tabel). Sprawdź to

AndyMac
źródło
6
Łącze jest przeznaczone dla serwera MS SQL ; to pytanie dotyczy MySQL
kucyki OMG
5
@OMG większość punktów w linku dotyczy wszystkich głównych RDBMS
RichardTheKiwi
5
@Richard aka cyberkiwi: Indeksy nie są objęte ANSI - to cud, że każdy sprzedawca używał podobnej terminologii. Ale nawet wtedy tylko SQL Server i MySQL używają terminologii „klastrowy” i „nieklastrowy” - oznacza to więcej w SQL Server niż MySQL. Nic nie gwarantuje, że zalecenia dla jednego dostawcy zostaną zastosowane do innego.
OMG Kucyki
3
@omg pierwsze 6 punktów dotyczy wszystkich dbms. pomiń te nieklastrowane, a poniżej znajduje się więcej punktów dotyczących ogólnego indeksowania, również na punkcie. Jeśli masz konkretne rzeczy, na które chcesz zwrócić uwagę, zadzwoń do nich. W przeciwnym razie wygląda na to, że negujesz wszystkie odpowiedzi, które z komentarzy (w tym Twoja usunięta odpowiedź), że nikt nie zgadza się z Twoją oceną.
RichardTheKiwi,
10

Musisz zrównoważyć potrzeby CRUD. Pisanie do tabel staje się powolne. Jeśli chodzi o to, gdzie narysować linię, zależy to od sposobu uzyskiwania danych (filtrowanie sortowania itp.).

Smandoli
źródło
a także każdy indeks zajmuje trochę miejsca w bazie danych
Acanthus
@Acanthus: Najmniejsze dostępne dyski twarde są mierzone w gigabajtach .
OMG Kucyki
4
@OMG, ale nie RAM, jak wskazuje Brian. to nie jest dobry pomysł, aby przechowywać więcej niż trzeba. buforowanie danych / indeksów w pamięci RAM, nośniki kopii zapasowych (wersje pasujące do taśmy itp.) - wszystko to jest wynikiem bezużytecznych indeksów
RichardTheKiwi
9
Obfitość zasobów nie jest powodem do marnotrawstwa lub nieefektywności.
Smandoli
6
To prawda, ale ograniczenia nie są takie, jakie były 10+ lat temu.
OMG Kucyki
2

Indeksowanie zajmie więcej przydzielonej przestrzeni zarówno z dysku, jak i pamięci RAM, ale także znacznie poprawi wydajność. Niestety, gdy osiągnie limit pamięci, system zrzeknie się miejsca na dysku i zagrozi wydajności. Praktycznie nie powinieneś indeksować żadnego pola, o którym myślisz, że nie obejmuje żadnego algorytmu przechodzenia przez dane, ani wstawiania, ani wyszukiwania (klauzula WHERE). Ale powinieneś, jeśli inaczej. Domyślnie musisz indeksować wszystkie pola. Pola, które powinieneś rozważyć odindeksowanie, to jeśli zapytania są używane tylko przez moderatora, chyba że wymagają również szybkości

Lionel Jerinho
źródło
2

ta odpowiedź jest oparta na mojej osobistej opinii. Do odpowiedzi używam logiki matematycznej

drugie pytanie dotyczyło granicy, na której się zatrzymać, Najpierw zróbmy jakieś obliczenia matematyczne, załóżmy, że mamy N wierszy z L polami w tabeli, jeśli zaindeksujemy wszystkie pola, otrzymamy L nowych tabel indeksowych, w których każda tabela będzie sortowana w w sensowny sposób dane pola indeksu, na pierwszy rzut oka, jeśli twój stół ma wagę W, stanie się W * 2 (1 tera stanie się 2 tera), jeśli masz 100 dużych tabel (pracowałem już w projekcie, w którym numer tabeli był około 1800 stolików) zmarnujesz 100 razy więcej miejsca (100 tera), to jest dalekie od rozsądku.

Jeśli zastosujemy indeksy we wszystkich tabelach, będziemy musieli pomyśleć o aktualizacjach indeksów, w których jedna aktualizacja wyzwoli aktualizację wszystkich indeksów to jest wybór wszystkich nieuporządkowanych odpowiedników w czasie

z tego wnioskuję, że masz w tym scenariuszu, że jeśli stracisz ten czas, lepiej stracić go w selekcji lub aktualizacji, ponieważ jeśli wybierzesz pole, które nie jest indeksowane, nie uruchomisz kolejnego wyboru na wszystkich polach, które są nie indeksowane

co indeksować?

klucze obce: jest koniecznością w oparciu o

klucz główny: nie jestem jeszcze tego pewien, może być, jeśli ktoś przeczyta to, może pomóc w tej sprawie

inne pola: pierwsza naturalna odpowiedź to połowa pozostałych fildów dlaczego: jeśli powinieneś indeksować więcej, nie jesteś daleko od najlepszej odpowiedzi, jeśli powinieneś indeksować mniej, nie jesteś również daleko, ponieważ wiemy, że żaden indeks nie jest zły i wszystkie zindeksowane jest również zły.

z tych 3 punktów mogę wywnioskować, że jeśli mamy pola L złożone z K kluczy, limit powinien być gdzieś blisko ((L-K)/2)+Kmniej więcej o L / 10

ta odpowiedź jest oparta na mojej logice i osobistych cenach

Mohammed Housseyn Taleb
źródło
1

Indeksowanie wszystkich kolumn w tabeli nie jest dobrym pomysłem. Chociaż sprawi to, że odczyt tabeli będzie bardzo szybki, zapisywanie będzie również znacznie wolniejsze. Zapisywanie do tabeli, w której każda kolumna jest indeksowana, wymagałoby umieszczenia nowego rekordu w tej tabeli, a następnie umieszczenia informacji z każdej kolumny w jej własnej tabeli indeksu.

Rachid Sakara
źródło
Nie jestem pewien, czy sprawiłoby, że czytanie tabeli było błyskawiczne, zwłaszcza jeśli tabela danych ma tylko 100 MB, ale index.table 300 MB lub więcej.
David
Wszystko, co powiedziałeś, zostało powiedziane wcześniej.
Vael Victus