開始
我有一個表,大約有一千萬條記錄,當我運作一個insert 指令向另一個表插入資料時,由于限制和索引的存在,導緻插入資料很慢。
但是這也給了我一個機會,來觀察 explain plan 是如何處理資料的。


我的test02 表,有一千萬條資料,下面我來拷貝資料:
由于資料量大,限制也在起作用,是以運作了很久(事實上兩天後崩潰了(我用的是虛拟機))。
在此期間,我開了另外的session, 來執行查詢:


其實如果執行 select count(*) from ptest, 由于前面的session 的插入動作耗時很久,尚未結束故尚未送出。是以傳回的結果是零。
那麼為何執行計劃分别在兩個子表中看到了 各一百多萬條的記錄呢?
PostgreSQL 的實體存儲結構中,沒有像oracle 那樣的rollback或undo segment,所有的資料映像,都存放在資料塊中。如果不進行vacuum操作,舊的已經送出的資料、剛剛刷入磁盤未送出的資料和已經送出的資料就都會在資料塊中。
如果我作一個程式,每1分鐘修改某表格資料的特定記錄一次但是不送出,隻要我的事務足夠長,那麼這将會不斷地刷入資料到資料塊中。這是PostgreSQL 的一個弱點,也是被人诟病之處。
可以說,在一個并發性很高的系統裡,每一次的sql 執行,其成本的一個重要方面,就是磁盤通路實體I/O,而由于PostgreSQL 把資料的前映像(送出的和未送出的)、目前映像(送出的和未送出的),都存放在一起,使得每個sql通路互相影響(因為有未送出的資料摻和),無疑地降低了性能。
在PostgreSQL 社群詢問的結果是,如果隻是想看近似的結果,不想用太大代價,可以從 pg_class 入手:
結束
本文轉自健哥的資料花園部落格園部落格,原文連結:http://www.cnblogs.com/gaojian/archive/2012/11/12/2765749.html,如需轉載請自行聯系原作者