CLUSTER
Jeśli zamierzasz używać CLUSTER
, wyświetlana składnia jest nieprawidłowa.
create CLUSTER ticket USING ticket_1_idx;
Uruchom raz:
CLUSTER ticket USING ticket_1_idx;
Ten może bardzo pomóc przy większych zestawach wyników. Nie tyle w przypadku zwróconego pojedynczego wiersza.
Postgres zapamiętuje, którego indeksu użyć przy kolejnych wywołaniach. Jeśli Twoja tabela nie jest tylko do odczytu, efekt pogarsza się z czasem i musisz powtarzać w określonych odstępach czasu:
CLUSTER ticket;
Prawdopodobnie tylko na niestabilnych partycjach. Zobacz poniżej.
Jednak , jeśli masz dużo aktualizacji, CLUSTER
(lub VACUUM FULL
) może w rzeczywistości negatywnie wpływać na wydajność. Odpowiednia ilość wzdęcia umożliwia UPDATE
umieścić nowe wersje wierszy na tej samej stronie danych i uniknąć konieczności zbyt częstego fizycznego rozszerzania podstawowego pliku w systemie operacyjnym. Możesz użyć starannie dostrojonego FILLFACTOR
aby uzyskać to, co najlepsze z obu światów:
- Współczynnik wypełnienia dla indeksu sekwencyjnego, którym jest PK
pg_repack
CLUSTER
przyjmuje blokadę na wyłączność na stole, co może stanowić problem w środowisku wielu użytkowników. Cytując instrukcję:
Gdy tabela jest klastrowana, ACCESS EXCLUSIVE
zamek jest na nim nabyty. Zapobiega to wszelkim innym operacjom na bazie danych (zarówno odczyt, jak i zapis ) od pracy na stole aż do CLUSTER
jest skończony.
Moje odważne podkreślenie. Rozważ alternatywę pg_repack
:
W przeciwieństwie do CLUSTER
i VACUUM FULL
działa on-line, bez trzymania wyłącznej blokady na przetwarzanych stołach podczas przetwarzania. pg_repack jest wydajny podczas uruchamiania, z wydajnością porównywalną do używania CLUSTER
bezpośrednio.
i:
pg_repack musi przyjąć wyłączną blokadę pod koniec reorganizacji.
Wersja 1.3.1 współpracuje z:
PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4
Wersja 1.4.2 współpracuje z:
PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10
Zapytanie
Zapytanie jest na tyle proste, że samo w sobie nie powoduje żadnych problemów z wydajnością.
Jednak słowo o poprawności :BETWEEN
konstrukcja zawiera granice. Twoje zapytanie obejmuje cały dzień 19 grudnia plus zapisy z 20 grudnia, godz. 00:00. To bardzo mało prawdopodobne wymóg. Są szanse, że naprawdę chcesz:
SELECT *
FROM ticket
WHERE created >= '2012-12-19 0:0'
AND created < '2012-12-20 0:0';
Wydajność
Po pierwsze, pytasz:
Dlaczego wybiera skanowanie sekwencyjne?
Twój EXPLAIN
dane wyjściowe wyraźnie pokazują Skanowanie indeksu , a nie sekwencyjne skanowanie tabeli. Musi być jakieś nieporozumienie.
Jeśli jesteś mocno naciskany na lepszą wydajność, możesz być w stanie poprawić rzeczy. Ale niezbędne informacje ogólne nie wchodzą w rachubę. Możliwe opcje to:
-
Możesz zapytać tylko o wymagane kolumny zamiast
*
w celu zmniejszenia kosztów transferu (i ewentualnie innych korzyści związanych z wydajnością). -
Możesz spojrzeć na partycjonowanie i umieść praktyczne wycinki czasu na oddzielnych stołach. W razie potrzeby dodaj indeksy do partycji.
-
Jeśli partycjonowanie nie jest opcją, inną powiązaną, ale mniej inwazyjną techniką byłoby dodanie jednego lub więcej indeksów częściowych .
Na przykład, jeśli najczęściej wysyłasz zapytania dotyczące bieżącego miesiąca , możesz utworzyć następujący indeks częściowy:CREATE INDEX ticket_created_idx ON ticket(created) WHERE created >= '2012-12-01 00:00:00'::timestamp;
CREATE
nowy indeks tuż przed początek nowego miesiąca. Możesz łatwo zautomatyzować zadanie za pomocą zadania cron. OpcjonalnieDROP
częściowe indeksy dla starych miesięcy później. -
Zachowaj całkowity indeks dodatkowo dla
CLUSTER
(które nie mogą działać na indeksach częściowych). Jeśli stare rekordy nigdy się nie zmieniają, partycjonowanie tabeli bardzo pomogłoby w tym zadaniu, ponieważ wystarczy ponownie klastrować nowsze partycje. Z drugiej strony, jeśli rekordy w ogóle się nie zmieniają, prawdopodobnie nie potrzebujeszCLUSTER
.
Jeśli połączysz dwa ostatnie kroki, wydajność powinna być niesamowita.
Podstawy wydajności
Być może brakuje Ci jednej z podstaw. Obowiązują wszystkie zwykłe porady dotyczące wydajności:
- https://wiki.postgresql.org/wiki/Slow_Query_Questions
- https://wiki.postgresql.org/wiki/Performance_Optimization