Próbowałem COUNT(*)
uzyskać tabelę ze 150 000 wierszy z kluczem podstawowym. Narzędzie to trwa około 5 minut, więc zorientowałem się, że jest to problem z indeksowaniem.
Powołując się na instrukcję PostgreSQL :
REINDEX jest podobny do upuszczania i ponownego tworzenia indeksu, ponieważ zawartość indeksu jest odbudowywana od zera. Jednak względy blokowania są raczej różne. REINDEX blokuje zapisy, ale nie odczytuje tabeli nadrzędnej indeksu. Pobiera także wyłączną blokadę na konkretnym przetwarzanym indeksie, który blokuje odczyty, które próbują użyć tego indeksu (...) Kolejne polecenie UTWÓRZ INDEKS blokuje zapisy, ale nie odczytuje; ponieważ indeksu nie ma, żaden odczyt nie będzie próbował go użyć, co oznacza, że nie będzie blokowania, ale odczyty mogą zostać wymuszone na drogie sekwencyjne skany.
Czy na podstawie własnego doświadczenia potrafisz powiedzieć:
- jest
REINDEXING
niebezpieczny? Czy może to zaszkodzić spójności danych? - Czy to może zająć dużo czasu?
- Czy to prawdopodobne rozwiązanie mojego scenariusza?
Aktualizacja:
Rozwiązaniem, które działało dla nas, było odtworzenie tego samego indeksu o innej nazwie, a następnie usunięcie starego indeksu.
Tworzenie indeksu jest bardzo szybkie i zmniejszyliśmy rozmiar indeksu z 650 MB do 8 MB. Używanie COUNT(*)
z between
zajmuje tylko 3 sekundy.
źródło
COUNT(*)
jest najlepszym wyborem:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.
Nie jestem pewien najlepszej odpowiedzi dla ciebie. Jednak ten wątek wydaje się oferować kilka dobrych sugestii: n http://postgresql.1045698.n5.nabble.com/count-performance-issue-td2067873.html
Jedna uwaga jest taka, że można zaimplementować WYZWALACZ, aby zachować liczbę wierszy w osobnej tabeli (jeśli aplikacje będą wywoływać COUNT (*)).
Kilka odpowiedzi sugeruje, że jest to objaw bazy danych, która nie została ostatnio wystarczająco odkurzona (sugerując, że autovacuum jest wyłączone na twoim serwerze lub w szczególności dla tej bazy danych)?
Inna sugestia wygląda następująco:
A ktoś zidentyfikowany jako A. Kretschmer zauważa:
Nie. Bieżąca implementacja indeksu nie zawiera informacji o widoczności wierszy w bieżącej transakcji. Musisz zeskanować całą tabelę danych, aby sprawdzić, czy bieżący wiersz jest widoczny w bieżącej transakcji.
... popierając mój komentarz o uprawnieniach na poziomie wiersza, które są problemem dotyczącym wydajności.
Moje wyszukiwanie pokazało również WikiVS: MySQL vs. PostgreSQL: COUNT (*) .
Możesz przejrzeć inne wyniki, które znalazłem, używając Google: wydajność licznika postgresql (*)
źródło