PostgreSQL GIN 和 GiST 索引類型

2021-08-27 15:10 更新

有兩種索引可以被用來加速全文搜索。注意全文搜索并非一定需要索引,但是在一個(gè)定期會被搜索的列上,通常需要有一個(gè)索引。

CREATE INDEX name ON table USING GIN(column);

創(chuàng)建一個(gè)基于 GIN(通用倒排索引)的索引。column必須是tsvector類型。

CREATE INDEX name ON table USING GIST (column [ { DEFAULT | tsvector_ops } (siglen = number) ] );

創(chuàng)建一個(gè)基于 GiST(通用搜索樹)的索引。column可以是tsvectortsquery類型。可選整數(shù)參數(shù)siglen確定以字節(jié)為單位的簽名長度(詳見下文)。

GIN 索引是更好的文本搜索索引類型。作為倒排索引,每個(gè)詞(詞位)在 其中都有一個(gè)索引項(xiàng),其中有壓縮過的匹配位置的列表。多詞搜索可以找到 第一個(gè)匹配,然后使用該索引移除缺少額外詞的行。GIN 索引只存儲 tsvector值的詞(詞位),并且不存儲它們的權(quán)重標(biāo)簽。因此, 在使用涉及權(quán)重的查詢時(shí)需要一次在表行上的重新檢查。

一個(gè) GiST 索引是有損的,這表示索引可能產(chǎn)生假匹配,并且有必要檢查真實(shí)的表行來消除這種假匹配(PostgreSQL在需要時(shí)會自動(dòng)做這一步)。GiST 索引之所以是有損的,是因?yàn)槊恳粋€(gè)文檔在索引中被表示為一個(gè)定長的簽名。以字節(jié)為單位的簽名長度由可選整數(shù)參數(shù) siglen 的值決定。 默認(rèn)簽名長度(未指定 siglen 時(shí))為 124 字節(jié),最大簽名長度為 2024 字節(jié)。該簽名通過哈希每一個(gè)詞到一個(gè) n 位串中的一個(gè)單一位來產(chǎn)生,通過將所有這些位 OR 在一起產(chǎn)生一個(gè) n 位的文檔簽名。當(dāng)兩個(gè)詞哈希到同一個(gè)位位置時(shí)就會產(chǎn)生假匹配。如果查詢中所有詞都有匹配(真或假),則必須檢索表行查看匹配是否正確。更長的簽名導(dǎo)致更精確的搜索(掃描索引的一小部分和更少的堆頁面),但代價(jià)是更大的索引。

GiST 索引可以被覆蓋,例如使用INCLUDE子句。 包含的列可以具有沒有任何 GiST 操作符類的數(shù)據(jù)類型。 包含的屬性將非壓縮存儲。

有損性導(dǎo)致的性能下降歸因于不必要的表記錄(即被證實(shí)為假匹配的記錄)獲取。因?yàn)楸碛涗浀碾S機(jī)訪問是較慢的,這限制了 GiST 索引的可用性。假匹配的可能性取決于幾個(gè)因素,特別是唯一詞的數(shù)量,因此推薦使用詞典來縮減這個(gè)數(shù)量。

注意GIN索引的構(gòu)件時(shí)間常??梢酝ㄟ^增加maintenance_work_mem來改進(jìn),而GiST索引的構(gòu)建時(shí)間則與該參數(shù)無關(guān)。

對大集合分區(qū)并正確使用 GIN 和 GiST 索引允許實(shí)現(xiàn)帶在線更新的快速搜索。分區(qū)可以在數(shù)據(jù)庫層面上使用表繼承來完成,或者是通過將文檔分布在服務(wù)器上并收集外部的搜索結(jié)果,例如通過外部數(shù)據(jù)訪問。后者是可能的,因?yàn)榕琶瘮?shù)只使用本地信息。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號