Postgresql之HOT技術簡析
背景:
PG實現了MVCC,但是沒有引入undo表空間,為實現多版本讀,所有的update操作都插入一個新版本行(delete-marked-old + insert-new),資料行的各個版本從老到新形成一個單向連結串列,即update chain。
pre-8.3,索引塊也是採用同樣的策略,即便update沒有更新任何索引列,舉例說明:
表t有兩個列(id , name),其中name上有索引 ind_name,現在表有2個資料行,分別稱為tuple1和tuple2
(1, 'a')
(0, 'b')
現在表上有3個資料行
(1, 'a') ---> (2, 'a') 這個是update chain, (1, 'a')此時被標記為deleted,且其指向(3, 'a')
(0, 'b')
而索引ind_name同樣會新增一個entry,儘管沒有更新索引列name
('a', tuple1_pos) --> ('a', tuple1_pos),第2個entry沒有存在的必要
('b', tuple2_pos)
這會導致索引佔用更多的空間,提升訪問代價
改進
從8.3開始,當update語句同時滿足下述兩個條件時,索引不會新增entry:
1 update沒有更新索引列;
2 表塊有足夠空間容納update產生的新版本行,即同一update chain上的所有版本必須位於同一個資料塊中。
同樣的例子,執行update t set id =id+ 1 where name = 'a'後
現在表上有3個資料行
(1, 'a') ---> (2, 'a')
(0, 'b')
而索引ind_name沒有改變
('a', tuple1_pos)
('b', tuple2_pos)
儘管資料行從(1, 'a')變成了(2, 'a'),但是ind_name的索引項仍然指向(1, 'a'),回表時透過遍歷update chain找到(2, 'a')
這種改進被稱為HOT(heap only tuple)
實現原理
PG資料塊由幾部分組成: 塊頭;行指標;資料行;塊尾
其中行指標指向對應行物理位置,其組成為(lp_offset, lp_flags, lp_len) = (15b, 2b, 15b)
lp_offset為元組在塊內偏移量,2^15=32768,因此PG的資料塊最大為32K;
lp_flags描述元組的狀態,有4個候選值:未使用;正常使用;hot重定向;死亡
lp_len為元組的長度
每個資料行都有一個行指標,當全表掃描時,會讀取塊內的所有行指標以獲取資料行。
資料行的頭部包含一些後設資料欄位,其中ctid標註該行物理位置(offset, len),和行指標有重複嫌疑,當形成update chain時,ctid指向的是連結串列中下一個版本的位置,依靠它才能完成遍歷。
當不斷執行update t set id =id +1 where name ='a' 時,block1會被撐爆,最終會變成如下形式:
block 1
(1, 'a') ---> (2, 'a') ---> .......
(0, 'b')
block 2
(N, 'a') ---> (N + 1, 'a')
此時索引會新增一個entry
('a', tuple1_pos) --> ('a', tuple3_pos)
('b', tuple2_pos)
延伸
innodb的索引元組結構為(索引列,主鍵),每次回表都透過主鍵掃描B+樹來定位資料塊,再借助頁目錄在塊內定位資料行物理位置。
這種方式的優點是資料行的物理位置發生改變且索引列值不變時,不需要更新索引,缺點是每次回表會多消耗2個IO(普通B+樹一般為3層)。
因此,當update沒有更新索引列時,相應的索引完全不受影響,不存在類似PG的煩惱。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-2121757/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL DBA(182) - HOTSQL
- GraphQL 技術淺析
- 淺析蜜罐技術
- PostgreSQL TOAST 技術解析SQLAST
- 容器技術之發展簡史
- 爬蟲技術淺析爬蟲
- 通訊系統之TDM技術和FDM技術簡介
- Java程式設計技術之淺析JVM記憶體Java程式設計JVM記憶體
- 淺析寬頻接入技術
- 淺析Java Web框架技術JavaWeb框架
- RPO攻擊技術淺析
- Android技術分享| Context淺析AndroidContext
- TSDB - VictoriaMetrics 技術原理淺析
- 網易新聞《娛樂圈畫傳》H5技術簡析H5
- Linux零複製技術淺析Linux
- PostgreSQL技術大講堂 - 第72講:索引與SQL調優之禁忌之戀SQL索引
- Innodb undo之 undo結構簡析
- [專業術語]淺析當代 LBS 技術
- PostgreSQL技術大講堂 - Part 2:PostgreSQL原始碼安裝SQL原始碼
- Docker與虛擬化技術淺析第一彈之docker與KubernetesDocker
- Java程式設計技術之淺析SPI服務發現機制Java程式設計
- 三維模型調色技術淺析模型
- 技術分享 | MySQL : SSL 連線淺析MySql
- PostgreSQL技術內幕(七)索引掃描SQL索引
- 讓動畫變得更簡單之FLIP技術動畫
- OCR技術簡介
- FRAM技術簡介
- 淺析三維模型輕量化技術方法模型
- LeetCode HOT 100:子集(簡單易懂的回溯)LeetCode
- Vue原始碼簡析之檢視生成(上)Vue原始碼
- 簡析網路競技遊戲匹配機制遊戲
- PostgreSQL MVCC快照機制淺析SQLMVC
- PostgreSQL DBA(19) - REDO point淺析SQL
- python技術簡介(三)Python
- 熱更新技術簡易原理及技術推薦
- PostgreSQL技術週刊第2期:用PostgreSQL解海盜分金問題SQL
- PostgreSQL技術週刊第20期:PostgreSQL何以支援豐富的NoSQL特性?SQL
- 聊聊技術管理(一)入行之技術管理和技術專家
- 深度學習技術發展趨勢淺析深度學習