本頁說明如何使用儲存的嵌入項目產生索引,以及如何使用 ScaNN
索引查詢 AlloyDB for PostgreSQL 的嵌入項目。如要進一步瞭解如何儲存嵌入內容,請參閱「儲存向量嵌入內容」。
AlloyDB alloydb_scann
:Google 開發的 PostgreSQL 擴充功能,可實作由 ScaNN 演算法驅動的高效率最鄰近索引。
ScaNN
索引是樹狀結構的量化索引,用於近似最近鄰搜尋。與 HNSW
相比,這項功能可縮短索引建構時間,並減少記憶體用量。此外,與 HNSW
相比,這項服務可根據工作負載提供更快的 QPS。
事前準備
開始建立索引前,請先完成下列必要條件。
系統會安裝以
pgvector
為基礎的vector
擴充功能 (由 Google 為 AlloyDB 擴充),以及alloydb_scann
擴充功能:CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
如要建立自動調整的 ScaNN 索引,請務必啟用
scann.enable_preview_features
標記。如不想啟用搶先體驗功能,或用於正式版例項,可以使用特定參數建立 ScaNN 索引。
建立自動調整的 ScaNN 索引
使用自動建立索引功能,即可簡化索引建立程序,自動建立經過最佳化的索引,提升搜尋效能,或兼顧索引建立時間和搜尋效能。
使用 AUTO
模式時,您只需要指定資料表名稱和嵌入資料欄,以及要使用的距離函式。您可以針對搜尋效能最佳化索引,或在索引建構時間和搜尋效能之間取得平衡。
您也可以使用 MANUAL
模式建立索引,並精細控管其他索引調整參數。
在 AUTO 模式中建立 ScaNN 索引
在 AUTO
模式下建立索引前,請注意下列幾點:
- 如果資料不足,AlloyDB 無法為資料表建立 ScaNN 索引。
- 在
AUTO
模式下建立索引時,您無法設定索引建立參數,例如num_leaves
。 - 在
AUTO
模式中建立的所有索引,預設都會啟用自動維護功能。
如要在 AUTO
模式下建立索引,請執行下列指令:
CREATE INDEX INDEX_NAME ON TABLE \
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
WITH (mode=AUTO', optimization='OPTIMIZATION');
更改下列內容:
INDEX_NAME
:要建立的索引名稱,例如my-scann-index
。資料庫會共用索引名稱。確認資料庫中每個資料表的索引名稱都不重複。TABLE
:要新增索引的資料表。EMBEDDING_COLUMN
:儲存vector
資料的資料欄。DISTANCE_FUNCTION
:要用於這個索引的距離函式。選擇下列其中一個選項:L2 距離:
l2
點積:
dot_product
餘弦距離:
cosine
OPTIMIZATION
:設為下列其中一個值:SEARCH_OPTIMIZED
:以較長的索引建構時間為代價,盡可能提升向量搜尋的召回率和縮短延遲時間。BALANCED
:建立索引,兼顧索引建構時間和搜尋效能。
在「手動」模式下建立 ScaNN
索引
如果您已啟用 scann.enable_preview_features
旗標,且想進一步控管微調參數,可以在 MANUAL
模式中建立索引。
如要在 MANUAL
模式下建立 ScaNN
索引,請執行下列指令:
CREATE INDEX INDEX_NAME ON TABLE \
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
WITH (mode='MANUAL, num_leaves=NUM_LEAVES_VALUE, [quantizer =QUANTIZER, max_num_levels=MAX_NUM_LEVELS]);
更改下列內容:
INDEX_NAME
:要建立的索引名稱,例如my-scann-index
。資料庫會共用索引名稱。確認資料庫中每個資料表的索引名稱都不重複。TABLE
:要新增索引的資料表。EMBEDDING_COLUMN
:儲存vector
資料的資料欄。DISTANCE_FUNCTION
:要用於這個索引的距離函式。選擇下列其中一個選項:L2 距離:
l2
點積:
dot_product
餘弦距離:
cosine
NUM_LEAVES_VALUE
:要套用至這個索引的分區數量。設為 1 到 1048576 之間的任何值。QUANTIZER
:要用於 K 平均值樹狀結構的量化器類型。預設值為 SQ8,可提供更優異的查詢效能,且喚回率損失極小 (通常少於 1-2%)。你也可以將其設為FLAT
,以達到 99% 以上的召回率。MAX_NUM_LEVELS
:K 平均叢集樹狀結構的層級數量上限。設為1
(預設值) 可進行兩層樹狀結構量化,設為2
則可進行三層樹狀結構量化。
您可以新增其他索引建立或查詢執行階段參數,調整索引。詳情請參閱「調整 ScaNN
索引」。
變更現有索引的模式
如果您使用 AUTO
模式建立 ScaNN 索引,並想手動調整索引,則必須將模式變更為 MANUAL
。
如要將模式變更為 MANUAL
,請按照下列步驟操作:
更新索引,將模式設為
MANUAL
:ALTER INDEX INDEX_NAME SET (mode = 'MANUAL', num_leaves = NUM_LEAVES_VALUE);
更改下列內容:
INDEX_NAME
:要建立的索引名稱,例如my-scann-index
。索引名稱會在資料庫中共用。確認資料庫中每個資料表的索引名稱皆不重複。NUM_LEAVES_VALUE
:要套用至這個索引的分區數量。設為 1 到 1048576 之間的任何值。
您可以新增其他索引建立或查詢執行階段參數,調整索引。詳情請參閱「調整
ScaNN
索引」。重建索引以套用參數:
REINDEX INDEX CONCURRENTLY INDEX_NAME;
如要將模式變更為 AUTO
,請完成下列步驟:
更新索引,將模式設為
AUTO
:ALTER INDEX INDEX_NAME SET (mode = 'AUTO');
重建索引以套用參數:
REINDEX INDEX CONCURRENTLY INDEX_NAME;
使用特定參數建立 ScaNN
索引
如果應用程式對回溯和索引建構時間有特定需求,可以手動建立索引。您可以根據工作負載建立兩層或三層樹狀結構索引。如要進一步瞭解如何調整參數,請參閱「調整 ScaNN
索引」。
兩層樹狀結構索引
如要使用 ScaNN 演算法,將兩層樹狀結構索引套用至含有儲存向量嵌入的資料欄,請執行下列 DDL 查詢:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE);
更改下列內容:
INDEX_NAME
:要建立的索引名稱,例如my-scann-index
。索引名稱會在資料庫中共用。請確保資料庫中每個資料表的索引名稱都不重複。TABLE
:要新增索引的資料表。EMBEDDING_COLUMN
:儲存vector
資料的資料欄。DISTANCE_FUNCTION
:要用於這個索引的距離函式。選擇下列其中一個選項:L2 距離:
l2
點積:
dot_product
餘弦距離:
cosine
NUM_LEAVES_VALUE
:要套用至這個索引的分區數量。請設為 1 到 1048576 之間的任何值。如要進一步瞭解如何決定這個值,請參閱「調整ScaNN
索引」。
三層樹狀結構索引
如要使用 ScaNN 演算法,為含有儲存向量嵌入的資料欄建立三層樹狀結構索引,請執行下列 DDL 查詢:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = 2);
建立索引後,您可以按照「使用指定文字進行最鄰近查詢」一文中的操作說明,執行最鄰近搜尋查詢,藉此使用索引。
請務必設定索引參數,在 QPS 和召回率之間取得適當平衡。如要進一步瞭解如何調整 ScaNN
索引,請參閱「調整 ScaNN
索引」。
如要在使用 real[]
資料類型 (而非 vector
) 的嵌入資料欄上建立這個索引,請將該資料欄轉換為 vector
資料類型:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);
請將 DIMENSIONS
改成嵌入資料欄的維度寬度。如要進一步瞭解如何尋找維度,請參閱向量函式中的 vector_dims
函式。
如要確保搜尋體驗一致,請在建立 ScaNN 索引時啟用自動維護功能。詳情請參閱「維護向量索引」。這項功能目前為預先發布版。
如要查看索引建立進度,請使用 pg_stat_progress_create_index
檢視畫面:
SELECT * FROM pg_stat_progress_create_index;
phase
欄會顯示索引建立作業的目前狀態。索引建構階段完成後,索引的資料列就不會顯示。
如要調整索引,以達到平均召回率和每秒查詢次數的平衡,請參閱「調整 ScaNN
索引」。
並行建構索引
為加快建立索引的速度,AlloyDB 可能會視資料集和所選索引類型,自動產生多個平行工作站。
如果您要建立 3 層 ScaNN 索引,或資料集超過 1 億列,通常會觸發平行索引建構作業。
雖然 AlloyDB 會自動調整平行工作站數量,但您可以使用 max_parallel_maintenance_workers
、max_parallel_workers
和 min_parallel_table_scan_size
PostgreSQL 查詢規劃參數,調整平行工作站。
執行查詢
將嵌入內容儲存到資料庫並建立索引後,即可開始查詢資料。您無法使用 alloydb_scann
擴充功能執行大量搜尋查詢。
如要找出嵌入向量最鄰近的語意鄰項,可以執行下列查詢範例,並設定與建立索引時相同的距離函式。
SELECT * FROM TABLE
ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
LIMIT ROW_COUNT
更改下列內容:
TABLE
:包含要與文字比較的嵌入內容的資料表。INDEX_NAME
:要使用的索引名稱,例如my-scann-index
。EMBEDDING_COLUMN
:包含儲存的嵌入內容的資料欄。DISTANCE_FUNCTION_QUERY
:要用於這項查詢的距離函式。根據建立索引時使用的距離函式,選擇下列其中一項:L2 距離:
<->
內積:
<#>
餘弦距離:
<=>
EMBEDDING
:您要找出最鄰近儲存語意鄰項的嵌入向量。ROW_COUNT
:要傳回的列數。如只要取得最佳單一比對結果,請指定
1
。
您也可以使用 embedding()
函式將文字翻譯成向量。由於 embedding()
會傳回 real
陣列,因此您必須先將 embedding()
呼叫明確轉換為 vector
,才能套用至其中一個最鄰近的鄰域運算子 (例如 <->
代表 L2 距離)。這些運算子隨後可以使用 ScaNN 索引,找出語意相似度最高的嵌入資料庫資料列。