PostgreSQL表的行數統計

2021-07-06 10:15:00 字數 4899 閱讀 8607

postgresql表的行數統計

在很多情況下我們需要知道乙個表的記錄數有多少。如果你發現你有這樣的需求,你還應該問問這樣的統計的精確度到底又多高。如果你在做會計報表,你需要非常的精確。如果你做乙個網頁的記數器,可能有一些誤差也是允許的。

使用count(*)

傳統的計算乙個表的行數的方法是使用count(*),但是count(*)非常的慢,尤其是對於乙個大表而言。

webstat=# select count(*) from rawlog;

count

---------

2058704

(1 row)

time: 7202.873 ms

從上邊的查詢可以看出,count(*)的速度是非常的慢的,因此你應當盡可能的避免使用count(*),

但是它仍然是最精確的一種方法。

使用系統表

count(*)的一種替代方法是通過查詢pg_class系統表獲取大致的行數。這個數值每次vacuum之後

變化。你統計的行數的誤差在vacuum之間刪除或者插入的行數,如果你統計的行數允許這樣的差值,

這種方法就是你最佳的選擇。記住,別使用這種方法在會計統計上。當你發出的vacuum越頻繁,則

你所得到的行數就越精確。

這個數值儲存在pg_class的reltuples欄位裡邊,下邊的查詢語句列出了public模式下的所有表

的行數:

select relname, reltuples 

from pg_class r join pg_namespace n 

on (relnamespace = n.oid) 

where relkind = 'r' and n.nspname = 'public';

物件的型別是表型別('r'),模式是public。相應的如果我們想看乙個表的行記錄數,我們可以

使用如下的語句:

select reltuples 

from pg_class r 

where relkind = 'r' and relname = 'mytable';

使用觸發器

如果你必須得到精確的記錄數,而又不想使用count(*)的話,那麼你可以考慮使用觸發器來維護

表的記錄數。這個辦法需要建立乙個insert trigger來增加數量以及乙個delete trigger 來減少

數量。具體的數量可以儲存在乙個單獨的表中。

建立乙個row_counts表,row_counts表包含乙個表名稱字段:relname,乙個行記錄數字段:

reltuples。首先你需要建立表,然後建立觸發器,最後初試化表的記錄數。

create table row_counts (

relname  text primary key,

reltuples   numeric);

我寫了乙個觸發器函式來處理表的insert和delete事件,我們可以很容易的通過tg_op來判斷操作

型別,tg_relname來獲取表的名稱。這兩個都是觸發器的特殊變數。

create or replace function count_trig()

returns trigger as d

ecla

rebe

gini

ftgo

p=′i

nser

t′th

enex

ecut

e′up

date

rowc

ount

sset

relt

uple

s=re

ltup

les+

1whe

rere

lnam

e=′′′||t

grel

name

||′′′′;r

etur

nnew

;els

iftg

op=′

dele

te′t

hene

xecu

te′u

pdat

erow

coun

tsse

trel

tupl

es=r

eltu

ples

−1wh

erer

elna

me=′′′||

tgre

lnam

e||′′′′;r

etur

nold

;end

if;e

nd;

language 'plpgsql';

同樣我也只寫了乙個函式來把所以的表上加上這個觸發器。你可以不需要這樣做。如果是這樣的話,你可以

寫乙個相同的函式來刪除觸發器。

create or replace function add_count_trigs()

returns void asde

clar

erec

reco

rd;q

text

;beg

info

rrec

inse

lect

reln

amef

romp

gcla

ssrj

oinp

gnam

espa

ceno

n(re

lnam

espa

ce=n

.oid

)whe

rere

lkin

d=′r

′and

n.ns

pnam

e=′p

ubli

c′lo

opq:

=′cr

eate

trig

ger′

||re

c.re

lnam

e||′

coun

tbef

orei

nser

tord

elet

eon′

;q:=q

||re

c.re

lnam

e||′

fore

achr

owex

ecut

epro

cedu

reco

untt

rig(

)′;e

xecu

teq;

endl

oop;

retu

rn;e

nd;

language 'plpgsql';

發出vacuum語句之後使用如下語句初試化表的記錄數:

insert into row_counts select relname, reltuples from pg_class;

可能還會存在一些錯誤,如任何在vacuum和建立觸發器之間完成的事物都將忽略掉,為了精確的統計,你需要

停止伺服器上的所有活動。

即便你可以在每個表上執行vacuum,但是有的時候如果你不確定vacuum是否執行,你可以寫個函式來完成相似

的功能。這個函式要比vacuum慢,而且如果你的資料庫活動比較頻繁的話也會有一些誤差。

create or replace function init_row_counts()

returns void asde

clar

erec

reco

rd;c

recr

ecor

d;be

ginf

orre

cins

elec

trel

name

from

pgcl

assr

join

pgna

mesp

acen

on(r

elna

mesp

ace=

n.oi

d)wh

erer

elki

nd=′

r′an

dn.n

spna

me=′

publ

ic′l

oopf

orcr

ecin

exec

ute′

sele

ctco

unt(

∗)as

rows

from

′||r

ec.r

elna

melo

op−−

noth

ingh

ere,

move

alon

gend

loop

;ins

erti

ntor

owco

unts

valu

es(r

ec.r

elna

me,c

rec.

rows

);en

dloo

p;re

turn

;end

; language 'plpgsql';

這個函式從pg_class裡邊查詢所有的表,對每個表使用count(*)獲取記錄數。把上邊的放在一塊,下邊

列出來了操作順序:

建立記錄行數的表。

建立觸發器函式。

如果可能停止伺服器的活動。

vacuum表。

在乙個事物裡邊,在表上新增觸發器,初試化記錄數。

這樣從次以後,你可以通過查詢行記錄數的表來或者相應表的記錄數。

PostgreSQL的建立表

postgresql的create table語句是用來在任何指定的的資料庫中建立乙個新錶。create table語句的基本語法如下 create table table name column1 datatype,column2 datatype,column3 datatype,columnn...

postgresql表分割槽

pg的表分割槽實際就是所說的分表,pg的表分割槽的是採用繼承表的方式。表繼承所有父表的檢查與約束都會被子表繼承,主外來鍵關係不會。乙個子表可以繼承多個父表,修改父表的表結構時,大多數情況下也會修改子表的結構定義。分割槽表就是把邏輯上的乙個大表分割成物理上的幾個小塊。好處 1 delete資料更快,只...

PostgreSQL表的匯入匯出

命令操作 資料的匯出 pg dump u postgres 使用者名稱 t 表名 資料庫名 預設時同使用者名稱 c fulldb.sql 資料的匯入 psql u postgres 使用者名稱 d 資料庫名 預設時同使用者名稱 c fulldb.sql pgadmin操作 資料的匯出 在庫名上右擊 ...