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操作 資料的匯出 在庫名上右擊 ...