Czy jest jakiś wzrost wydajności w indeksowaniu pola logicznego?

104

Właśnie mam napisać zapytanie zawierające plik WHERE isok=1. Jak sama nazwa wskazuje, isokjest polem boolowskim (a właściwie TINYINT(1) UNSIGNEDustawionym na 0 lub 1 w razie potrzeby).

Czy jest jakiś wzrost wydajności w indeksowaniu tego pola? Czy silnik (w tym przypadku InnoDB) działałby lepiej czy gorzej patrząc w górę indeksu?

Niet the Dark Absol
źródło
możliwy duplikat pól boolowskich Indexing
Maxim Krizhanovsky

Odpowiedzi:

82

Nie całkiem. Powinieneś pomyśleć o tym jak o książce. Gdyby w książce były tylko 3 rodzaje słów i indeksowałbyś je wszystkie, miałbyś taką samą liczbę stron indeksowych jak zwykłe strony.

Byłby wzrost wydajności, gdyby było stosunkowo niewiele rekordów o jednej wartości. Na przykład, jeśli masz 1000 rekordów, a 10 z nich to PRAWDA, byłoby przydatne, jeśli szukaszisok = 1

Jak wspomniał Michael Durrant, powoduje również spowolnienie zapisu.

EDYCJA: Możliwe duplikacje: Indeksowanie pól logicznych

Tutaj wyjaśnia, że ​​nawet jeśli masz indeks, jeśli masz zbyt wiele rekordów, i tak go nie używa. MySQL nie używa indeksu podczas sprawdzania = 1, ale używa go z = 0

Michael Koper
źródło
4
Wygląda na to, że „tak: 2 - nie: 1”. Ktoś tu się myli, ale kto?
Niet the Dark Absol
4
Nie jest to do końca poprawne, bez indeksu mySql musi skanować całą tabelę, aby znaleźć odpowiednie wiersze.
ilanco
4
w przeciwnym razie przeszukałby cały indeks. (co jest w większości przypadków tak samo długie)
Michael Koper
1
To może mieć znaczenie. Po prostu skróć czas wykonania o połowę zapytania, dodając indeks, a zapisy są na tyle rzadkie i tanie, że tak naprawdę nie przejmujemy się karą. Jak ze wszystkim, nie zakładaj, mierz (również dlatego, że bazy danych nie zawsze zachowują się tak, jak byś logicznie się po nich spodziewał)
Eelco
6
Zakłada to równy rozkład między TRUE i FALSE. Jak wspomniano w @oucil poniżej, jeśli szukasz wartości logicznej, która jest dość rzadka, może to zająć trochę czasu. Nie mówię, że zawsze powinieneś indeksować, ale zakładam, że natura twoich danych i twoich zapytań ma również znaczenie w przypadku większości silników baz danych.
mahemoff
118

Żeby dokładniej przyjrzeć się kilku innym odpowiedziom, ponieważ z mojego doświadczenia wynika, że ​​ci, którzy patrzą na takie pytania, są na tym samym statku, co my, wszyscy słyszeliśmy, że indeksowanie pól boolowskich jest bezcelowe, a jednak ...

Mamy tabelę z około 4 milionami wierszy, tylko około 1000 na raz będzie miało oznaczony przełącznik boolowski i właśnie to szukamy. Dodanie indeksu do naszego pola boolowskiego przyspieszyło zapytania o rząd wielkości, skróciło się z około 9+ sekund do ułamka sekundy.

oucil
źródło
Tak, chociaż powinieneś definitywnie spróbować zrozumieć `` dlaczego '' rzeczy, zawsze dokonuj pomiarów obok i wypróbuj różne rzeczy w swoim rzeczywistym zbiorze danych, aby zobaczyć, czy twoja teoria pasuje do rzeczywistego zachowania silnika db (byłbyś zaskoczony ... )
Eelco
8
@Eelco Masz rację, ale w tym przypadku wynik faktycznie pasuje do podstawowej teorii. Podstawowa idea, że ​​powinna być pomijalna, ma sens tylko wtedy, gdy istnieje około 50% prawdopodobieństwa, że ​​trafisz na przedmioty pasujące do Twojego wyszukiwania. Następnie, aby znaleźć 100 dopasowań, DB musi dokonać iteracji 200 pozycji. Ale jeśli elementy pasują tylko w 1% przypadków, należałoby powtórzyć 10.000 pozycji.
mahemoff
7
Lubię, gdy ludzie próbują różnych rzeczy w terenie i przekazują informacje zwrotne na temat wydajności, zamiast tylko filozofować.
Viktor Joras
WHERE my_col > 0 zamiast tego my_col = 1wydaje się, że pomaga przyspieszyć
Aaron
28

Zależy to od rzeczywistych zapytań i selektywności kombinacji indeks / zapytanie.

Przypadek A : stan WHERE isok = 1i nic więcej:

SELECT *
FROM tableX
WHERE isok = 1
  • Jeśli indeks jest wystarczająco selektywny (powiedzmy, że masz 1 mln wierszy i tylko 1 KB isok = 1), wówczas silnik SQL prawdopodobnie użyje indeksu i będzie szybszy niż bez niego.

  • Jeśli indeks nie jest wystarczająco selektywny (powiedzmy, że masz 1 mln wierszy i więcej niż 100 000 isok = 1), silnik SQL prawdopodobnie nie użyje indeksu i nie przeprowadzi skanowania tabeli.

Przypadek B : stan WHERE isok = 1i więcej rzeczy:

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17

Następnie zależy to od innych posiadanych indeksów. Indeks „on” another_columnbyłby prawdopodobnie bardziej selektywny niż indeks, isokktóry ma tylko dwie możliwe wartości. Indeks na (another_column, isok)lub (isok, another_column)byłby jeszcze lepszy.

ypercubeᵀᴹ
źródło
Myślę, że jest to bardziej poprawna odpowiedź w porównaniu z pierwszą. także dystrybucja danych.
11

Zależy to od dystrybucji danych.

Wyobraź sobie, że mam książkę z 1000 ściśle wpisanych stron, a jedyne słowa w mojej książce to „tak” i „nie” powtarzane w kółko i rozprowadzane losowo. Gdyby poproszono mnie o zaznaczenie wszystkich przypadków „tak”, czy indeks na końcu książki pomógłby? To zależy.

Gdyby istniał pół na pół losowy rozkład „tak” i „nie”, wyszukiwanie w indeksie nie pomogłoby. Indeks sprawiłby, że książka byłaby dużo większa, a poza tym szybciej bym zaczął od początku i przeszukiwał każdą stronę, szukając wszystkich przypadków „tak” i zakreślając je, zamiast sprawdzać każdy element w indeks, a następnie pobieranie odniesienia z wpisu indeksu do strony, do której się odnosi.

Ale gdyby było, powiedzmy, tylko dziesięć przypadków „tak” w mojej tysiącostronicowej książce, a wszystko inne było po prostu milionami „nie”, to indeks zaoszczędziłby mi mnóstwo czasu na znajdowaniu tych dziesięciu przykładów „tak” i okrążaniu ich .

Tak samo jest w bazach danych. Jeśli jest to dystrybucja 50:50, indeks nie pomoże - silnik bazy danych lepiej będzie po prostu przeglądać dane od początku do końca (pełne skanowanie tabeli), a indeks po prostu powiększy bazę danych i wolniej pisać i aktualizować. Ale jeśli jest to coś w rodzaju dystrybucji 4000: 1 (zgodnie z oucil w tym wątku), to przeszukiwanie indeksu może znacznie przyspieszyć to, jeśli jest to pozycja 1 na 4000, której szukasz.

Jinlye
źródło
5

Nie, zwykle nie.

Zwykle indeksujesz pola do wyszukiwania, gdy mają one wysoką selektywność / liczność. W większości tabel liczność pola boolowskiego jest bardzo niska. Spowoduje to również, że twoje zapisy będą nieco wolniejsze.

Michael Durrant
źródło
3

W rzeczywistości zależy to od zapytań, które uruchamiasz. Ale ogólnie tak, jak również indeksowanie pola dowolnego innego typu.

Maksym Polshcha
źródło
2

Tak, indeks poprawi wydajność, sprawdź wyjście EXPLAIN zi bez indeksu.

Z dokumentów:

Indeksy służą do szybkiego znajdowania wierszy z określonymi wartościami kolumn. Bez indeksu MySQL musi zaczynać się od pierwszego wiersza, a następnie czytać całą tabelę, aby znaleźć odpowiednie wiersze. Im większy stół, tym więcej to kosztuje. Jeśli tabela ma indeks dla danych kolumn, MySQL może szybko określić pozycję, do której należy szukać w środku pliku danych, bez konieczności przeglądania wszystkich danych.

Myślę, że można również bezpiecznie powiedzieć, że indeks nie ZMNIEJSZY wydajności w tym przypadku, więc musisz tylko na tym zyskać.

ilanco
źródło
2
Indeks daje dużo danych na twardym dysku i sprawia, że ​​zapisy są wolniejsze, więc nie tylko zyskujesz na tym.
Michael Koper
1
To prawda, ale w tym przypadku TINYINT(1) UNSIGNEDkolumna, rozmiar danych będzie mały.
ilanco
A dodatkowe obciążenie zapisu prawdopodobnie jest dość niskie
Eelco
Czy rozmiar indeksu nie będzie rósł wraz z liczbą wierszy, na które wskazuje, a nie tylko rozmiarem indeksowanego pola?
bilard