PostgresQL建立索引如何避免寫資料鎖定

2021-09-06 07:01:58 字數 1431 閱讀 8559

問題源自乙個帥哥在建索引發生表鎖的問題。先介紹一下postgresql的建索引語法:

version:9.1

create [ unique ] index [ concurrently ] [ name ] on table [ using method ]     (  [ collate collation ] [ opclass ] [ asc | desc ] [ nulls  ] [, ...] )     [ with ( storage_parameter = value [, ... ] ) ]     [ tablespace tablespace ]     [ where predicate ]
這裡不解釋語法的諸多引數使用(排序,使用方法,填充因子等),主要說一下concurrently的使用場景。

正常情況下postgresql建立普通btree索引時會阻塞dml(insert,update,delete)操作,直到索引完成,期間讀操作不受 阻塞。當只有乙個使用者操作這當然沒問題,但是在生產環境,併發比較高的情況下,特別是大表建索引就不能這麼操作了,不然使用者要跳起來罵娘了,點個按鈕一天 還沒反應過來。

--使用

--***

當然了,使用這個引數是有***的,不使用這個引數建索引時db只掃瞄一次表,使用這個引數時,會引發db掃兩次表,同時等待所有潛在會讀到該索引的事務結束,這麼一來,系統的cpu和io,記憶體等會受一點影響,所以綜合考慮,仍然讓使用者自行選擇,而不是預設。

--失敗

在使用concurrently引數建索引時,有可能會遇到失敗的情況,比如建唯一索引索引發現資料有重複,又或者使用者發現建索引時建錯字段的,取消建索 引操作了。此時該錶上會存在乙個索引,這是因為帶這個引數的建索引命令一經發出,就首先會在系統的日誌表裡先插乙個索引記錄進去,又因為這個索引最終建失 敗了,所以會被標記乙個invalid的狀態,如下:

postgres=# \d t_kenyon        table "public.t_kenyon"  column |  type   | modifiers  --------+---------+-----------  col    | integer |  indexes:     "idx" btree (col) invalid
--重建

遇到上述失效的索引重建時兩個辦法,乙個是drop index index_name,然後再執行create index concurrently。還有乙個是執行reindex index_name命令,但是後者不支援concurrent引數。

--總結

在生產上執行建立索引命令時最好帶上此引數,因為多消耗一點系統資源和時間來換取使用者的不間斷訪問更新是相對值得的。 如果是索引重建,可以再在原基礎上建立乙個不同名的相同索引,然後取消老的索引。

PostgreSQL索引建立,檢視與刪除問題

建立方式 create index index sfzqfxx czrkgmsfhm on zck.ods gat sfzqfxx using btree czrkgmsfhm 或者create index index sfzqfxx czrkgmsfhm on zck.ods gat sfzqfx...

PostgreSQL中的索引

索引是一種快速查詢資料的方法,它記錄了表中一列或多列與其物理位置之間的對應關係。常用的索引有b tree,hash,gist及gin等。1 b tree索引適合處理等值查詢和範圍查詢。2 hash只適合處理簡單的等值查詢。3 gist支援很多不同的索引策略。4 gin反轉索引,可以處理包含多個鍵的值...

PostgreSQL 什麼是索引?

什麼是索引?索引是提高資料庫效能的常用途徑。比起沒有索引,使用索引可以讓資料庫伺服器更快找到並獲取特定行。但是索引同時也會增加資料庫系統的日常管理負擔,因此我們應該聰明地使用索引。每種索引演算法都分別適合某些特定的查詢型別,因為他們用了不同的索引結構。pg裡的所有索引都是 從屬索引 索引在物理上與它...