Ada tiga cara untuk menghitung seperti ini, masing-masing dengan pengorbanan mereka sendiri.
Jika Anda menginginkan hitungan yang benar, Anda harus menjalankan pernyataan SELECT seperti yang Anda gunakan terhadap setiap tabel. Ini karena PostgreSQL menyimpan informasi visibilitas baris di baris itu sendiri, bukan di tempat lain, sehingga penghitungan akurat hanya dapat relatif terhadap beberapa transaksi. Anda mendapatkan hitungan dari apa yang dilihat transaksi itu pada saat transaksi dijalankan. Anda bisa mengotomatiskan ini untuk dijalankan terhadap setiap tabel dalam database, tetapi Anda mungkin tidak membutuhkan tingkat akurasi atau ingin menunggu selama itu.
Pendekatan kedua mencatat bahwa pengumpul statistik melacak kira-kira berapa banyak baris yang "hidup" (tidak dihapus atau usang oleh pembaruan selanjutnya) setiap saat. Nilai ini dapat dimatikan sedikit di bawah aktivitas berat, tetapi umumnya merupakan perkiraan yang baik:
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Itu juga dapat menunjukkan kepada Anda berapa banyak baris yang mati, yang merupakan nomor yang menarik untuk dipantau.
Cara ketiga adalah mencatat bahwa perintah ANALYZE sistem, yang dieksekusi oleh proses autovacuum secara teratur pada PostgreSQL 8.3 untuk memperbarui statistik tabel, juga menghitung estimasi baris. Anda bisa ambil yang seperti ini:
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;
Yang mana dari pertanyaan ini yang lebih baik digunakan adalah sulit untuk dikatakan. Biasanya saya membuat keputusan berdasarkan apakah ada informasi yang lebih berguna yang juga ingin saya gunakan di dalam pg_class atau di dalam pg_stat_user_tables. Untuk keperluan penghitungan dasar hanya untuk melihat seberapa besar hal-hal besar secara umum, keduanya harus cukup akurat.
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
? Database Redshift saya tidak memiliki kolom itu. Ini adalah turunan dari Postgres 8.0.2.pg_stat_user_tables
) mengembalikan sebagian besar noln_live_tup
untuk saya karenaANALYZE
belum pernah dijalankan. Daripada berjalanANALYZE
pada setiap skema / tabel dan menunggu selamanya untuk jawaban, saya pertama-tama memeriksa hasilnya menggunakan 'pendekatan ketiga' dan yang satu (menggunakanpg_class
) mengembalikan jumlah yang sangat akurat.Berikut ini adalah solusi yang tidak memerlukan fungsi untuk mendapatkan hitungan yang akurat untuk setiap tabel:
query_to_xml
akan menjalankan kueri SQL yang diteruskan dan mengembalikan XML dengan hasilnya (jumlah baris untuk tabel itu). Bagian luarxpath()
kemudian akan mengekstrak informasi jumlah dari xml itu dan mengubahnya menjadi angkaTabel turunan tidak benar-benar diperlukan, tetapi membuat
xpath()
sedikit lebih mudah untuk dipahami - jika tidak, keseluruhanquery_to_xml()
harus diteruskan kexpath()
fungsi.sumber
query_to_jsonb()
.select count(*)
di setiap meja.xpath()
fungsi ini hanya diterapkan pada satu baris - hasil daricount(*)
Untuk mendapatkan taksiran, lihat jawaban Greg Smith .
Untuk mendapatkan penghitungan yang tepat, jawaban lain sejauh ini terganggu dengan beberapa masalah, beberapa di antaranya serius (lihat di bawah). Inilah versi yang semoga lebih baik:
Dibutuhkan nama skema sebagai parameter, atau
public
jika tidak ada parameter yang diberikan.Untuk bekerja dengan daftar skema tertentu atau daftar yang berasal dari kueri tanpa mengubah fungsinya, ia dapat dipanggil dari dalam kueri seperti ini:
Ini menghasilkan output 3-kolom dengan skema, tabel dan jumlah baris.
Sekarang ada beberapa masalah di jawaban lain yang fungsi ini hindari:
Nama tabel dan skema tidak boleh disuntikkan ke dalam SQL yang dapat dieksekusi tanpa dikutip, baik dengan
quote_ident
atau dengan fungsi yang lebih modernformat()
dengan%I
string formatnya. Kalau tidak, beberapa orang jahat dapat memberi nama meja merekatablename;DROP TABLE other_table
yang benar-benar valid sebagai nama tabel.Bahkan tanpa masalah injeksi SQL dan karakter lucu, nama tabel mungkin ada dalam varian yang berbeda menurut kasus. Jika sebuah tabel dinamai
ABCD
dan yang lainabcd
,SELECT count(*) FROM...
harus menggunakan nama yang dikutip jika tidak akan melewatiABCD
dan menghitungabcd
dua kali. The%I
format melakukan ini secara otomatis.information_schema.tables
daftar tipe komposit khusus selain tabel, bahkan ketika table_type adalah'BASE TABLE'
(!). Sebagai konsekuensinya, kita tidak dapat melanjutkaninformation_schema.tables
, jika tidak kita berisiko memilikiselect count(*) from name_of_composite_type
dan itu akan gagal. OTOHpg_class where relkind='r'
harus selalu berfungsi dengan baik.Jenis COUNT () adalah
bigint
, tidakint
. Tabel dengan lebih dari 2,15 miliar baris mungkin ada (menjalankan penghitungan (*) pada mereka adalah ide yang buruk).Tipe permanen tidak perlu dibuat untuk fungsi untuk mengembalikan resultset dengan beberapa kolom.
RETURNS TABLE(definition...)
adalah alternatif yang lebih baik.sumber
Jika Anda tidak keberatan data yang berpotensi basi, Anda dapat mengakses statistik yang sama dengan yang digunakan oleh pengoptimal kueri .
Sesuatu seperti:
sumber
ANALYZE
di atas meja, statistiknya bisa keluar. Ini adalah pertanyaan tentang pemuatan basis data dan bagaimana basis data dikonfigurasikan (jika statistik diperbarui lebih sering, statistik akan lebih akurat, tetapi ini dapat mengurangi kinerja runtime). Pada akhirnya, satu-satunya cara untuk mendapatkan data yang akurat adalah menjalankanselect count(*) from table
semua tabel.Jawaban praktis dan mudah bagi orang yang mencoba mengevaluasi rencana Heroku mana yang mereka butuhkan dan tidak bisa menunggu penghitung baris lambat heroku untuk disegarkan:
Pada dasarnya Anda ingin menjalankan
\dt
dipsql
, menyalin hasil untuk editor teks favorit Anda (akan terlihat seperti ini:), lalu jalankan pencarian regex dan ganti seperti ini:
untuk:
yang akan memberi Anda sesuatu yang sangat mirip dengan ini:
(Anda harus menghapus yang terakhir
union
dan menambahkan tanda titik koma di bagian akhir secara manual)Jalankan
psql
dan Anda selesai.sumber
select '$1', count(*) from $1 union/g
/g
(menyimpanunion
) dan menambahkan satu titik koma (;
) di bagian paling akhir. Jangan lupa untuk menghapus yang terakhirunion
sebelum titik koma.union
sebelum titik koma" adalah apa yang saya maksud :) Menambahkan kata "terakhir" untuk memperjelasTidak yakin apakah jawaban dalam bash dapat Anda terima, tetapi FWIW ...
sumber
select count(*) from table_name;
di OP!Saya biasanya tidak mengandalkan statistik, terutama di PostgreSQL.
sumber
dsql2('select count(*) from livescreen.'||table_name)
atau lebih baik dapat diubah menjadi fungsi tersendiri.Saya tidak ingat URL tempat saya mengumpulkan ini. Tetapi harap ini akan membantu Anda:
Eksekusi
select count_em_all();
akan membuat Anda menghitung baris semua tabel Anda.sumber
quote_ident(t_name.relname)
) untuk memastikan dukungan yang tepat untuk nama yang tidak biasa ("nama kolom", misalnya).SELECT * FROM count_em_all() as r ORDER BY r.num_rows DESC;
Dua Langkah Sederhana:
(Catatan: Tidak perlu mengubah apa pun - cukup salin tempel)
1. buat fungsi
2. Jalankan kueri ini untuk mendapatkan jumlah baris untuk semua tabel
atau
Untuk mendapatkan jumlah baris dengan tab
sumber
Saya membuat variasi kecil untuk memasukkan semua tabel, juga untuk tabel non-publik.
gunakan
select count_em_all();
untuk menyebutnya.Semoga Anda menemukan ini berguna. Paul
sumber
Ini berhasil untuk saya
sumber
Saya suka jawaban Daniel Vérité . Tetapi ketika Anda tidak bisa menggunakan pernyataan CREATE, Anda bisa menggunakan solusi bash atau, jika Anda pengguna windows, yang PowerShell:
sumber
Saya ingin total dari semua tabel + daftar tabel dengan jumlah mereka. Sedikit seperti bagan kinerja tempat sebagian besar waktu dihabiskan
Anda tentu saja dapat menempatkan
LIMIT
klausa pada hasil dalam versi ini juga sehingga Anda mendapatkann
pelanggar terbesar serta total.Satu hal yang harus diperhatikan tentang ini adalah Anda perlu membiarkannya untuk sementara waktu setelah impor massal. Saya menguji ini dengan hanya menambahkan 5.000 baris ke database di beberapa tabel menggunakan data impor nyata. Ini menunjukkan 1800 catatan selama sekitar satu menit (mungkin jendela yang dapat dikonfigurasi)
Ini didasarkan dari https://stackoverflow.com/a/2611745/1548557 kerja, jadi terima kasih dan pengakuan itu untuk permintaan untuk digunakan dalam CTE
sumber