詳解PostgreSQL的TOAST大字段存儲(chǔ)方式
PostgreSQL為“大字段“的物理存儲(chǔ)提供了TOAST功能,通過合適的配置策略能夠減少IO次數(shù)和掃描塊數(shù),進(jìn)而提升查詢速度。
TOAST:The Oversized-Attribute Storage Technique
特點(diǎn):
PostgreSQL采用固定頁面大小(通常是8Kb,不象oracle在運(yùn)行期間有多種選擇),元組不能跨越多個(gè)頁面,無法實(shí)現(xiàn)“大字段值“的直接存儲(chǔ)。TOAST提供了解決方法,允許大的字段值被壓縮或分裂為多個(gè)物理行。
PostgreSQL只為部分?jǐn)?shù)據(jù)類型支提供TOAST支持,為支持TOAST,數(shù)據(jù)類型必須是變長(zhǎng)(varlena)的類型。前32位存儲(chǔ)著以字節(jié)記的數(shù)值總長(zhǎng)度(包括長(zhǎng)度本身)。
TOAST采用最高的兩個(gè)二進(jìn)制位用于標(biāo)識(shí)壓縮與行外存儲(chǔ),因此“大字段“的邏輯長(zhǎng)度被限制在了1GB2^(32-2)-1)。
兩個(gè)位都是零,表示數(shù)值未經(jīng)過TOAST方式的數(shù)值;
第32位為1,表示該數(shù)值被壓縮,使用前必須先解壓縮;
第31位為1,表示該數(shù)值采用行外存儲(chǔ),此時(shí)只是存儲(chǔ)著一個(gè)指針,該指針指向其他的地方。另外30個(gè)位表示數(shù)據(jù)的實(shí)際尺寸,而不是解壓縮或者從線外數(shù)據(jù)抓過來之后的邏輯尺寸。
行外數(shù)據(jù)被分裂成(如果壓縮過,以壓縮后為參考)最多TOAST_MAX_CHUNK_SIZE(這個(gè)數(shù)值略小于BLCKSZ/4,或者缺省 2K字節(jié))字節(jié)的塊,每個(gè)塊都作為獨(dú)立的行在TOAST表里為所屬表存儲(chǔ)。每個(gè)TOAST表都有字段chunk_id,chunk_seq和chunk_data。在chunk_id和chunk_seq上有一個(gè)唯一索引,提供對(duì)數(shù)值的快速檢索。
只有表中存儲(chǔ)超過BLCKSZ/4字節(jié)(通常是2Kb)的行才會(huì)觸發(fā),對(duì)字段進(jìn)行壓縮和行外存儲(chǔ),直到小于BLCKSZ/4字節(jié),或者無法得到更好的結(jié)果的時(shí)候才停止。UPDATE操作過程中,未改變的字段的數(shù)值通常原樣保存;因此UPDATE行外存儲(chǔ)的記錄時(shí),如果行外數(shù)據(jù)值沒有變化,將不會(huì)帶來TOAST開銷存在。
TOAST代碼識(shí)別四種不同的存儲(chǔ)可TOAST字段的策略:
PLAIN避免壓縮或者行外存儲(chǔ)。只對(duì)那些非TOAST數(shù)據(jù)類型才有效。
EXTENDED允許壓縮和行外存儲(chǔ)。大多數(shù)TOAST數(shù)據(jù)類型的缺省值。首先進(jìn)行壓縮,如果行仍然太大,則進(jìn)行行外存儲(chǔ)。
EXTERNAL允許行外存儲(chǔ),不許壓縮。使用 EXTERNAL將令那些在 text 和 bytea 字段上的子字串操作更快(代價(jià)是增加了存儲(chǔ)空間),因此這些操作是經(jīng)過優(yōu)化的:如果行外數(shù)據(jù)沒有壓縮,那么它們只抓取需要的部分。
MAIN允許壓縮,不允許行外存儲(chǔ)。當(dāng)數(shù)據(jù)值壓縮過后仍然太大將會(huì)采用行外存儲(chǔ)。每個(gè)可以 TOAST 的數(shù)據(jù)類型都為該數(shù)據(jù)類型的字段聲明一個(gè)缺省策略,但是特定表的字段的存儲(chǔ)策略可以用ALTER TABLE SET STORAGE修改。
優(yōu)點(diǎn):
相對(duì)直接的存儲(chǔ)方式來說,數(shù)據(jù)經(jīng)過TOAST方式后,單個(gè)或者連續(xù)數(shù)據(jù)塊中能夠存儲(chǔ)更多的數(shù)據(jù)值,對(duì)于訪問非“大字段”時(shí),能夠大量減少掃描塊數(shù)或者物理IO次數(shù);
對(duì)于極少訪問的含“大字段”記錄,經(jīng)過手動(dòng)修改存儲(chǔ)屬性,采用TOAST方式,即便值小于2K的情況下同樣能夠帶來很好的效果。
針對(duì)系統(tǒng)數(shù)據(jù)訪問特定,靈活的采用TOAST存儲(chǔ)策略總能夠?yàn)橄到y(tǒng)帶來性能的提升。
題外話:oracle的大字段的存儲(chǔ)采用了行外的方式,對(duì)大字段默認(rèn)進(jìn)行段存儲(chǔ),同時(shí)系統(tǒng)默認(rèn)創(chuàng)建索引。將大字段根據(jù)磁盤配置進(jìn)行單獨(dú)存儲(chǔ),也是提升oracle部署性能的常見方式。
原文標(biāo)題:postgresql TOAST存儲(chǔ)方式
鏈接:http://www.cnblogs.com/daduxiong/archive/2010/08/23/1806706.html
【編輯推薦】