Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Indexy - jak stosować?
Forum PHP.pl > Forum > Bazy danych
phpion
Hejka,
aż wstyd się przyznać ale do tej pory nie zaprzątałem sobie tym głowy i robiłem indexy na pojedyczne kolumny. Chciałbym się jednak dowiedzieć czy jest sens robienia czegoś takiego:
Mam tabelę, w której są pola np.
- login varchar
- haslo varchar
- aktywny enum("0", "1")
Indexy stawiałem dla każdego z pól osobno. Jednak najczęściej tworzę zapytanie, w którym nie wybieram rekordu po 1 warunku (np. WHERE login="nanana") tylko 3 na raz (WHERE login="nanana" AND haslo="ooo" AND aktywny="1"). Czy w takim przypadku nie powinienem utworzyć również indexu:
INDEX (login, haslo, aktywny)
? Jeśli tak to to by oznaczalo, że należy tworzyć indexy na wszystkie kombinacje danych?
Pozdrawiam: pion
JaRoPHP
Cytat(phpion.com @ 16.12.2007, 13:05:34 ) *
Jeśli tak to to by oznaczalo, że należy tworzyć indexy na wszystkie kombinacje danych?
Na pewno nie - pamiętaj, że indeksy zajmują miejsce, często bardzo dużo miejsca (nie raz zdarzało się, że ponad 70% miejsca na dysku zajmowały nie dane, a indeksy). Nie ma sensu tworzyć nadmiarowych indeksów.
Cytat
Duża liczba indeksów jest uzasadniona w sporadycznych przypadkach, zawsze jednak w momencie napotkania tabel wymagających dużej liczby indeksów warto ponownie rozważyć poprawność projektu.

Kiedy np. nie ma sensu stosować indeksów:
- gdy trzeba przeszukać całą tabelę (np. aby zliczyć, ilu użytkowników ma status aktywny, a ilu nieaktywny),
- gdy wyszukiwana wartość w kolumnie jest działaniem jakiejś funkcji (np. substr).

W Twoim przypadku dałbym indeks złożony na kolumny: login, haslo, aktywny. Należy pamiętać, że będzie on także użyteczny, gdy będziesz wyszukiwał tylko wg loginu, bądź tylko według loginu i hasła (porównania oczywiście muszą być w tej samej kolejności, w jakiej tworzą indeks).
Cytat
Indeks złożony jest w pełni użyteczny nawet w przypadku, gdy nie są określone niektóre kolumny klucza, pod warunkiem że są określone wszystkie kolumny z początku klucza

// Cytaty
"SQL. Sztuka programowania." /S. Faroult, P.Robson/
phpion
Cytat(JaRoPHP @ 16.12.2007, 15:45:32 ) *
W Twoim przypadku dałbym indeks złożony na kolumny: login, haslo, aktywny. Należy pamiętać, że będzie on także użyteczny, gdy będziesz wyszukiwał tylko wg loginu, bądź tylko według loginu i hasła (porównania oczywiście muszą być w tej samej kolejności, w jakiej tworzą indeks).

O taką informację mi chodziło, dzięki serdeczne! thumbsupsmileyanim.gif

// EDIT:
Jednak coś jeszcze nie daje mi spokoju. Mając taką tabelę:
  1. CREATE TABLE property (
  2. id SMALLINT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. region_id TINYINT(2) UNSIGNED NOT NULL,
  4. standard TINYINT(1) UNSIGNED NOT NULL,
  5. coord_x SMALLINT(3) UNSIGNED NULL,
  6. coord_y SMALLINT(3) UNSIGNED NULL,
  7. is_promoted ENUM ("0", "1") DEFAULT "0",
  8. is_luxury ENUM ("0", "1") DEFAULT "0",
  9. is_active ENUM ("0", "1") DEFAULT "1",
  10.  
  11. PRIMARY KEY (id),
  12.  
  13. CONSTRAINT FOREIGN KEY (region_id) REFERENCES region (id) ON DELETE CASCADE,
  14.  
  15. INDEX (region_id, is_active),
  16. INDEX (standard),
  17. INDEX (is_luxury)
  18. ) Engine=InnoDB DEFAULT CHARSET=UTF8;

jak powinieniem założyć indexy? Dane będą zawsze (!) wyszukiwane po region_id oraz is_active oraz opcjonalnie jeśli user wybierze standard to po standardzie oraz jeśli zaznaczy is_luxury to po tym polu.
Z góry dzięki za info.
pion
JaRoPHP
Cytat(phpion.com @ 16.12.2007, 14:13:13 ) *
Dane będą zawsze (!) wyszukiwane po region_id oraz is_active oraz opcjonalnie jeśli user wybierze standard to po standardzie oraz jeśli zaznaczy is_luxury to po tym polu.

Rozumiem, że są możliwe następujące sytuacje wyszukiwania:
- po polach: region_id, is_active
- lub po polach: region_id, is_active, standard
- lub po polach: region_id, is_active, is_luxury
- lub po polach: region_id, is_active, standard, is_luxury.

W takiej sytuacji spróbowałbym z indeksami:
  1. INDEX (region_id, is_active, standard)
  2. INDEX (is_luxury)
Moim zdaniem, nie ma sensu tworzyć osobnego indeksu dla pola standard...
phpion
Ok, chyba zaczaiłem jak to działa. Dzięki jeszcze raz smile.gif
DeyV
Cytat
porównania oczywiście muszą być w tej samej kolejności, w jakiej tworzą indeks).

Hmm - a to dlaczego?
Przecież dla optymalizatora zapytań nie ma znaczenia kolejność warunków w WHERE

Cytat
W Twoim przypadku dałbym indeks złożony na kolumny: login, haslo, aktywny.


A ja zrezygnowałbym z hasła zarówno w Index, jak i w zapytaniu.
W indexie nie jest potrzebne, bo jak sądzę, masz bazę gdzie Login jest Unique, więc i tak nie pojawi się nigdy kombinacja gdzie będzie 1 login i wiele haseł, stąd też index na haśle nigdy nie będzie wykorzystany.

A w zapytaniu unikałbym tego z względów czystego bezpieczeństwa - wiele zapytań jest logowanych, często wyświetlane są w trakcie debugowania, tak więc szkoda by było otwarcie wyświetlić tą informację.
JaRoPHP
Cytat(DeyV @ 26.12.2007, 18:59:24 ) *
Hmm - a to dlaczego?
Przecież dla optymalizatora zapytań nie ma znaczenia kolejność warunków w WHERE

Z tą kolejnością jednak byłbym ostrożny. Niby nie ma znaczenia, jednak optymalizatory bywająz awodne i nie zawsze wybierają najszybszą drogę zapytania. Tutaj odsyłam do podanej wyżej literatury.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.