Kiedy dodanie indeksu spowalnia
Tabela z liczbami dziennymi ma jeden klucz: licznik i data razem. Pięć miejsc w kodzie zadaje jej inne pytanie — nie „ten licznik w czasie", tylko „wszystkie liczniki w tych dniach". Galeria na stronie głównej, lista najlepszych, mapa witryny, wykres 90-dniowy i liczby stanu. Bez indeksu na kolumnie daty każde z nich czyta wszystkie 114 113 wierszy.
Ten indeks przyspiesza galerię dziesięciokrotnie. Nie został założony. Oto pomiar, który o tym zdecydował.
Jedno zapytanie zrobiło się dużo szybsze
Galeria pyta o liczniki, które miały dziś ruch. Bez indeksu na dacie przechodzi całą tabelę; z indeksem odszukuje jedną datę i czyta 443 wiersze. Z 61,5 milisekundy zrobiło się 6,1. To nie jest subtelny wynik, i gdyby był jedyną zmierzoną rzeczą, indeks byłby już w bazie.
Dwa zapytania zrobiły się wolniejsze
Mapa witryny pyta o czternaście dni i zwolniła o 19 %. Liczby stanu pytają o rok i zwolniły o 10 %. W obu przypadkach planista zapytań przeszedł z klucza głównego na nowy indeks i wybrał gorzej.
To ta część, którą warto zrozumieć, bo to nie błąd planisty. Czytanie zakresu przez indeks wtórny znaczy: znaleźć pasujące wiersze w indeksie i pobrać każdy z nich z tabeli. Dla wąskiego wycinka to okazja. Dla czternastu dni z trzynastu miesięcy to wciąż mnóstwo wierszy pobieranych pojedynczo, a zwykłe przejście przez tabelę — czytane w porządku fizycznym, który lubią dyski i pamięci podręczne — wygrywa. Planista o tym nie wie. Widzi zakres i indeks, i bierze go.
Nie da się powiedzieć „używaj tego indeksu tylko do galerii". Indeks jest dostępny dla każdego zapytania dotykającego tej kolumny, a planista weźmie go wszędzie tam, gdzie jego szacunki tak podpowiedzą. Założenie indeksu to zmiana w każdym zapytaniu na tej tabeli, a nie w tym jednym, o którym się myślało.
Razem: nic
Przez wszystkie pięć z 555 milisekund zrobiły się 524. Poprawa 1,1-krotna, która na Raspberry Pi i tak wydającym te strony z pamięci podręcznej nie jest warta zmiany schematu.
Wykres 90-dniowy wygląda na poprawę o 9 %. Nie jest liczona i warto powiedzieć dlaczego. Każde zapytanie mierzono trzy razy: bez indeksu, z indeksem, potem znów bez. Jeśli drugi przebieg bez indeksu nie ląduje blisko pierwszego, różnicą była maszyna, a nie zmiana. Przy wykresie 90-dniowym oba przebiegi bez indeksu różniły się o 13,8 % — więcej niż wielkość, którą chciałoby się ogłosić. Ten wiersz nie mierzy więc niczego i jako nic jest podawany.
Jak mierzono i dlaczego to ma znaczenie
Nie na działającej tabeli. Skrypt robi kopię, pracuje na kopii i na końcu ją usuwa. Założenie indeksu na tabeli produkcyjnej po to, żeby zobaczyć, co się stanie, to rzecz, którą na jedną niespodziankę można zrobić raz.
Zapytania są prawdziwe, wzięte z kodu, razem ze złączeniem z tabelą liczników. Wcześniejsza wersja tego testu używała uproszczonego zastępnika i dała dużo bardziej ekscytującą odpowiedź: dwadzieścia razy szybciej. Tego uproszczonego zapytania nikt nie zadaje.
Jaka liczba by wyszła
Gdyby mierzyć zwyczajnie — wziąć zapytanie, które wydaje się wolne, i zmierzyć przed i po — odpowiedź brzmiałaby „dziesięć razy szybciej, wdrażamy". Indeks by wszedł, galeria by przyspieszyła, mapa witryny i strona stanu by zwolniły, i nikt by tego nie powiązał, bo nikt na te dwie nie patrzył.
Taki jest ogólny kształt sprawy. Zmiany we wspólnej infrastrukturze nie da się ocenić na przypadku, który ją wywołał. Pytanie nie brzmi „czy to pomaga temu, na co właśnie patrzę", tylko „co jeszcze tego dotyka i co się z tym stanie".
Jest wersja, która mogłaby zadziałać: indeks niosący obie kolumny, datę na początku, tak żeby galerię dało się obsłużyć z samego indeksu, bez wracania do tabeli. Może też nie kusiłby planisty przy szerszych zakresach. To nie jest zmierzone, więc nie jest zaleceniem — to następna rzecz, która trafi na kopię.