Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak działają indeksy MySQL?

Pierwszą rzeczą, którą musisz wiedzieć, jest to, że indeksy to sposób na uniknięcie skanowania pełnej tabeli w celu uzyskania wyniku, którego szukasz.

Istnieją różne rodzaje indeksów, które są zaimplementowane w warstwie pamięci masowej, więc nie ma między nimi żadnego standardu, a ponadto zależą one od używanego silnika pamięci masowej.

InnoDB i indeks B+Tree

W przypadku InnoDB najpopularniejszym typem indeksu jest indeks oparty na B+Drzewo, który przechowuje elementy w posortowanej kolejności. Ponadto nie musisz uzyskiwać dostępu do rzeczywistej tabeli, aby uzyskać zindeksowane wartości, co znacznie przyspiesza powrót zapytania.

„Problem” związany z tym typem indeksu polega na tym, że aby użyć indeksu, musisz wykonać zapytanie o wartość znajdującą się najbardziej po lewej stronie. Jeśli więc indeks ma dwie kolumny, powiedzmy last_name i name_name, kolejność zapytań do tych pól jest bardzo ważna .

Tak więc, biorąc pod uwagę poniższą tabelę:

CREATE TABLE person (
    last_name VARCHAR(50) NOT NULL,
    first_name VARCHAR(50) NOT NULL,
    INDEX (last_name, first_name)
);

To zapytanie skorzystałoby z indeksu:

SELECT last_name, first_name FROM person
WHERE last_name = "John" AND first_name LIKE "J%"

Ale następna nie

SELECT last_name, first_name FROM person WHERE first_name = "Constantine"

Ponieważ pytasz o first_name pierwsza kolumna i nie jest to pierwsza kolumna z lewej strony w indeksie.

Ten ostatni przykład jest jeszcze gorszy:

SELECT last_name, first_name FROM person WHERE first_name LIKE "%Constantine"

Ponieważ teraz porównujesz skrajną prawą część prawego pola w indeksie.

Indeks skrótu

Jest to inny typ indeksu, który niestety obsługuje tylko zaplecze pamięci. Jest błyskawiczny, ale przydatny tylko do pełnych wyszukiwań, co oznacza, że ​​nie można go używać do operacji takich jak > , < lub LIKE .

Ponieważ działa tylko dla zaplecza pamięci, prawdopodobnie nie będziesz go często używać. Głównym przypadkiem, o którym teraz myślę, jest ten, w którym tworzysz w pamięci tabelę tymczasową z zestawem wyników z innego wyboru i wykonujesz wiele innych wyborów w tej tabeli tymczasowej przy użyciu indeksów mieszających.

Jeśli masz duży VARCHAR pole, możesz "emulować" użycie indeksu skrótu podczas korzystania z B-Tree, tworząc kolejną kolumnę i zapisując w niej skrót o dużej wartości. Załóżmy, że przechowujesz adres URL w polu, a wartości są dość duże. Możesz także utworzyć pole liczb całkowitych o nazwie url_hash i użyj funkcji skrótu, takiej jak CRC32 lub jakakolwiek inna funkcja skrótu do mieszania adresu URL podczas wstawiania go. A następnie, gdy potrzebujesz zapytać o tę wartość, możesz zrobić coś takiego:

SELECT url FROM url_table WHERE url_hash=CRC32("http://gnu.org");

Problem z powyższym przykładem polega na tym, że ponieważ CRC32 funkcja generuje dość mały hash, będziesz miał dużo kolizji w wartościach haszowanych. Jeśli potrzebujesz dokładnych wartości, możesz rozwiązać ten problem, wykonując następujące czynności:

SELECT url FROM url_table 
WHERE url_hash=CRC32("http://gnu.org") AND url="http://gnu.org";

Nadal warto haszować, nawet jeśli liczba kolizji jest wysoka, ponieważ wykonasz tylko drugie porównanie (łańcuchowe) z powtarzającymi się haszami.

Niestety, używając tej techniki, nadal musisz trafić w tabelę, aby porównać url pole.

Podsumuj

Kilka faktów, które możesz wziąć pod uwagę za każdym razem, gdy chcesz porozmawiać o optymalizacji:

  1. Porównanie liczb całkowitych jest znacznie szybsze niż porównywanie ciągów. Można to zilustrować przykładem emulacji indeksu skrótu w InnoDB .

  2. Być może dodanie dodatkowych kroków w procesie sprawi, że będzie on szybszy, a nie wolniejszy. Można to zilustrować faktem, że możesz zoptymalizować SELECT dzieląc go na dwa kroki, sprawiając, że pierwszy przechowuje wartości w nowo utworzonej tabeli w pamięci, a następnie wykonuje cięższe zapytania w tej drugiej tabeli.

MySQL ma też inne indeksy, ale myślę, że B+Tree jest najczęściej używany, a hash jest dobrze wiedzieć, ale możesz znaleźć inne indeksy w Dokumentacja MySQL .

Gorąco polecam lekturę książki "High Performance MySQL", powyższa odpowiedź była zdecydowanie oparta na rozdziale o indeksach.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Znajdź i zamień całą bazę danych mysql

  2. Błąd krytyczny Wordpress:Nieprzechwycony błąd:Wywołanie niezdefiniowanej funkcji mysql_connect() w /wp-includes/wp-db.php:1570

  3. UPUŚĆ TABELĘ, JEŚLI ISTNIEJE w MySQL

  4. Zmień kolumnę MySQL na AUTO_INCREMENT

  5. Wywołanie funkcji składowej execute() na wartości logicznej in