Istnieją trzy sposoby na obliczenie tego rodzaju, każdy z własnymi kompromisami.
Jeśli chcesz prawdziwej liczby, musisz wykonać instrukcję SELECT, taką jak ta, której użyłeś dla każdej tabeli. Wynika to z faktu, że PostgreSQL przechowuje informacje o widoczności wiersza w samym wierszu, a nie gdziekolwiek indziej, więc każda dokładna liczba może dotyczyć tylko niektórych transakcji. Otrzymujesz informację o tym, co widzi ta transakcja w momencie jej wykonania. Możesz to zautomatyzować, aby działało z każdą tabelą w bazie danych, ale prawdopodobnie nie potrzebujesz takiego poziomu dokładności lub nie chcesz czekać tak długo.
Drugie podejście zauważa, że moduł gromadzący statystyki śledzi w przybliżeniu, ile wierszy jest „na żywo” (nie usuwanych ani nieaktualnych przez późniejsze aktualizacje) w dowolnym momencie. Ta wartość może być nieco wyłączona przy dużym obciążeniu, ale ogólnie jest dobrym oszacowaniem:
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Może to również pokazać liczbę martwych wierszy, co samo w sobie jest interesującą liczbą do monitorowania.
Trzecim sposobem jest zwrócenie uwagi na to, że systemowa komenda ANALYZE, która jest regularnie wykonywana przez proces autovacuum od PostgreSQL 8.3 w celu aktualizacji statystyk tabeli, również oblicza oszacowanie wiersza. Możesz pobrać ten w ten sposób:
SELECT
nspname AS schemaname,relname,reltuples
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE
nspname NOT IN ('pg_catalog', 'information_schema') AND
relkind='r'
ORDER BY reltuples DESC;
Trudno powiedzieć, które z tych zapytań jest lepsze. Zwykle podejmuję tę decyzję na podstawie tego, czy są bardziej przydatne informacje, których chcę również użyć w pg_class, czy w pg_stat_user_tables. Dla podstawowych celów liczenia, aby zobaczyć, jak duże są rzeczy w ogóle, oba powinny być wystarczająco dokładne.
with tbl as (SELECT table_schema,table_name FROM information_schema.tables where table_name not like 'pg_%' and table_schema in ('public')) select table_schema, table_name, (xpath('/row/c/text()', query_to_xml(format('select count(*) as c from %I.%I', table_schema, table_name), false, true, '')))[1]::text::int as rows_n from tbl ORDER BY 3 DESC;
n_live_tup
? Moja baza danych Redshift nie ma tej kolumny. Jest pochodną Postgres 8.0.2.pg_stat_user_tables
) zwróciłon_live_tup
dla mnie głównie zera , ponieważANALYZE
nigdy nie zostało uruchomione. Zamiast uruchamiać sięANALYZE
na każdym schemacie / tabeli i czekać wiecznie na odpowiedź, najpierw sprawdziłem wyniki, stosując „trzecie podejście”, a ten (wykorzystującypg_class
) zwrócił bardzo dokładne liczby.Oto rozwiązanie, które nie wymaga funkcji, aby uzyskać dokładną liczbę dla każdej tabeli:
query_to_xml
uruchomi przekazane zapytanie SQL i zwróci XML z wynikiem (liczba wierszy dla tej tabeli). Zewnętrznyxpath()
wyodrębni następnie informacje o liczbie z tego xml i skonwertuje je na liczbęTabela pochodna nie jest tak naprawdę konieczna, ale
xpath()
nieco łatwiej ją zrozumieć - w przeciwnym razie całośćquery_to_xml()
musiałaby zostać przekazana doxpath()
funkcji.źródło
query_to_jsonb()
.select count(*)
na każdym stole.xpath()
funkcja jest stosowana tylko do jednego wiersza - wynikcount(*)
Aby uzyskać oszacowania, zobacz odpowiedź Grega Smitha .
Aby uzyskać dokładne liczby, inne dotychczasowe odpowiedzi są nękane niektórymi problemami, niektóre z nich poważnymi (patrz poniżej). Oto wersja, która, mam nadzieję, jest lepsza:
Przyjmuje nazwę schematu jako parametr lub
public
jeśli nie podano żadnego parametru.Aby pracować z określoną listą schematów lub listą pochodzącą z zapytania bez modyfikowania funkcji, można ją wywołać z poziomu zapytania takiego:
Daje to wynik 3-kolumnowy ze schematem, tabelą i wierszami.
Oto kilka problemów w innych odpowiedziach, których ta funkcja unika:
Nazwy tabel i schematów nie powinny być wstrzykiwane do wykonywalnego SQL bez cytowania, ani za pomocą,
quote_ident
ani za pomocą bardziej nowoczesnejformat()
funkcji z jej%I
ciągiem formatu. W przeciwnym razie złośliwa osoba może nazwać swoją tabelę,tablename;DROP TABLE other_table
która jest całkowicie poprawna jako nazwa tabeli.Nawet bez iniekcji SQL i problemów z zabawnymi znakami nazwa tabeli może występować w wariantach różniących się wielkością liter. Jeśli tabela jest nazwana
ABCD
i innaabcd
,SELECT count(*) FROM...
musi użyć cytowanej nazwy, w przeciwnym razie pominieABCD
i policzyabcd
dwa razy.%I
Formatu robi to automatycznie.information_schema.tables
wyświetla niestandardowe typy kompozytów oprócz tabel, nawet gdy typ_tabeli to'BASE TABLE'
(!). W związku z tym nie możemy powtarzaćinformation_schema.tables
, w przeciwnym razie ryzykujemy,select count(*) from name_of_composite_type
że to się nie powiedzie. OTOHpg_class where relkind='r'
powinien zawsze działać dobrze.Typ COUNT () to
bigint
nieint
. Mogą istnieć tabele z ponad 2,15 miliardami wierszy (choć liczenie (*) jest na nich złym pomysłem).Nie trzeba tworzyć typu stałego, aby funkcja zwracała zestaw wyników z kilkoma kolumnami.
RETURNS TABLE(definition...)
jest lepszą alternatywą.źródło
Jeśli nie przeszkadza Ci potencjalnie nieaktualne dane, możesz uzyskać dostęp do tych samych statystyk, które są wykorzystywane przez optymalizator zapytań .
Coś jak:
źródło
ANALYZE
na stole, statystyki mogą się znacznie pogorszyć . Jest to kwestia obciążenia bazy danych i konfiguracji bazy danych (jeśli statystyki są aktualizowane częściej, statystyki będą bardziej dokładne, ale może to zmniejszyć wydajność środowiska wykonawczego). Ostatecznie jedynym sposobem na uzyskanie dokładnych danych jest uruchomienieselect count(*) from table
wszystkich tabel.Chwytliwa, praktyczna odpowiedź dla osób, które próbują ocenić, jakiego planu Heroku potrzebują i nie mogą się doczekać odświeżenia wolnego licznika wierszy heroku:
Zasadniczo chcesz uruchomić
\dt
wpsql
skopiuj wyniki do swojego ulubionego edytora tekstu (będzie wyglądać następująco:), a następnie uruchom wyszukiwanie wyrażeń regularnych i zamień w następujący sposób:
do:
co da ci coś bardzo podobnego do tego:
(Musisz usunąć ostatni
union
i ręcznie dodać średnik na końcu)Uruchom
psql
i gotowe.źródło
select '$1', count(*) from $1 union/g
/g
(zachowaćunion
) i dodać jeden średnik (;
) na samym końcu. Nie zapomnij usunąć ostatniegounion
przed średnikiem.union
przed średnikiem”, co miałem na myśli :) Dodano słowo „ostatni”, aby wyjaśnićNie jestem pewien, czy odpowiedź w bash jest dla Ciebie akceptowalna, ale FWIW ...
źródło
select count(*) from table_name;
w PO!Zwykle nie polegam na statystykach, szczególnie w PostgreSQL.
źródło
dsql2('select count(*) from livescreen.'||table_name)
lub lepiej, może zostać przekształcona w własną funkcję.Nie pamiętam adresu URL, z którego to pobrałem. Ale mam nadzieję, że to powinno ci pomóc:
Wykonanie
select count_em_all();
powinno dać ci liczbę wierszy wszystkich twoich tabel.źródło
quote_ident(t_name.relname)
), Aby zapewnić odpowiednią obsługę nietypowych nazw (na przykład „nazwa kolumny”).SELECT * FROM count_em_all() as r ORDER BY r.num_rows DESC;
Proste dwa kroki:
(Uwaga: nic nie trzeba zmieniać - wystarczy skopiować wklej)
1. Utwórz funkcję
2. Uruchom to zapytanie, aby uzyskać liczbę wierszy dla wszystkich tabel
lub
Aby uzyskać wiersze, liczy się tabela
źródło
Wprowadziłem niewielką odmianę, aby uwzględnić wszystkie tabele, również dla tabel niepublicznych.
użyj,
select count_em_all();
aby to nazwać.Mam nadzieję, że okaże się to przydatne. Paweł
źródło
To zadziałało dla mnie
źródło
Lubię Daniel Verite za odpowiedź . Ale jeśli nie możesz użyć instrukcji CREATE, możesz użyć rozwiązania bash lub, jeśli jesteś użytkownikiem systemu Windows, PowerShell:
źródło
Chciałem sumę ze wszystkich tabel + listę tabel z ich liczbą. Trochę jak wykres wydajności, w którym spędzono najwięcej czasu
Możesz oczywiście dodać
LIMIT
klauzulę do wyników w tej wersji, aby uzyskać zarówno największychn
przestępców, jak i ogółem.Jedną z rzeczy, na które należy zwrócić uwagę, jest konieczność pozostawienia go przez chwilę po imporcie masowym. Przetestowałem to, dodając 5000 wierszy do bazy danych w kilku tabelach, używając rzeczywistych danych importu. Pokazywał 1800 rekordów przez około minutę (prawdopodobnie konfigurowalne okno)
Jest to oparte na pracy https://stackoverflow.com/a/2611745/1548557 , więc dziękuję i uznajesz to za zapytanie do użycia w CTE
źródło