PGVector是一個高效的向量資料庫外掛程式,支援多種向量計算演算法和資料類型,同時還能夠高效儲存與查詢以向量表示的AI Embedding。本文檔將為您介紹PGVector的背景、原理、使用方法及其他相關資訊。
背景資訊
隨著資料科學和機器學習等技術的迅速發展,向量計算已經成為了巨量資料領域中最常見的計算任務之一。PolarDB PostgreSQL版(相容Oracle)作為一種廣泛使用的關係型資料庫,結合PGVector外掛程式後通過自訂的資料類型和儲存方法,使得高維向量計算變得更加高效快速。
資料庫內部使用高維度(包括主流文本嵌入模型)儲存表示輸入輸出的情境,PGVector外掛程式最高支援16000維度。
前提條件
支援的PolarDB PostgreSQL版(相容Oracle)的版本如下:
Oracle文法相容 2.0(核心小版本2.0.14.9.0及以上)
Oracle文法相容 1.0(核心小版本1.1.35及以上)
您可通過如下語句查看PolarDB PostgreSQL版(相容Oracle)的核心小版本號碼:
SHOW polar_version;注意事項
PX支援通過sort遍曆高維向量。
PX不支援索引查詢。
原理介紹
PGVector的索引演算法是IVFFlat(同pase外掛程式的向量演算法)。IVFFlat是一種基於倒排索引的近似最近鄰搜尋演算法,可以用於高效地查詢向量之間的相似性。它將向量空間分為若干個劃分地區,每個地區都包含一些向量,並建立倒排索引,用於快速地尋找與給定向量相似的向量。
IVFFlat是IVFADC演算法的簡化版本,適合於召回精度要求高,但對查詢耗時要求不嚴格(100ms層級)的情境。相比其他演算法,IVFFlat演算法具有高召回率、高精度、演算法和參數簡單、空間佔用小的優勢。
PGVector外掛程式的實現基於PolarDB PostgreSQL版(相容Oracle)的擴充機制,利用C語言編寫實現多種向量計算演算法和資料類型。其中外掛程式演算法的具體流程如下:
高維空間中的點基於隱形的聚類屬性,按照K-Means等聚類演算法對向量進行聚類處理,使得每個類簇有一個中心點。
檢索向量時首先遍曆計算所有類簇的中心點,找到與目標向量最近的n個類簇中心。
遍曆計算n個類簇中心所在聚類中的所有元素,經過全域排序得到距離最近的k個向量。
使用指南
PGVector外掛程式可以順序及索引檢索高維向量,樣本列出了簡單使用方法。
召回率和效能介紹。
PGVector外掛程式在0.5.0版本前使用的IVFFlat索引構建速度快,相比於無任何索引能夠提升一定的查詢效能,但召回率表現一般,也會消耗一定的記憶體。新增的HNSW索引在召回率和效能上都有更加優秀的表現,但索引構建速度更慢,記憶體使用量量更高。在使用向量索引來查詢向量資料時,往往需要在效能與召回率兩個維度上權衡利弊,這裡介紹兩種提升召回率的索引參數配置方法。
HNSW
m:表示在每個索引元素之間存在多少雙向連結(或路徑)。預設值為16,取值範圍為2~100。將該值設定為一個較高的數量,可以增加召回量。但也會顯著增加索引產生時間,並可能影響查詢效能。ef_construction:表示在索引中添加元素時,需要檢查的近鄰數。預設值為64,取值範圍為4~100。增加該值可以增加召回量,但是會增加索引構建時間。該值必須至少是m的兩倍。CREATE TABLE vecs (id int PRIMARY KEY, embedding vector(1536)); CREATE INDEX ON vecs USING hnsw(embedding vector_l2_ops) WITH (m=16, ef_construction=64);必須指定使用HNSW索引的操作符類。例如,使用HNSW索引的餘弦,可以使用如下命令:
CREATE INDEX ON vecs USING hnsw(embedding vector_cosine_ops);可以先選擇預設的索引構建配置項來最佳化構建時間。如果沒有得到資料集的預期召回量,先增加
ef_construction值,再調整m值。可以通過設定較大的hnsw.ef_search值來增加查詢召回,例如,設定為100,值越大往往召回越高。IVFFlat
lists:PGVector採樣表中所有向量的聚類中心數量。CREATE INDEX ON vecs USING ivfflat(embedding) WITH (lists=100);
關於索引和更多的參數方法介紹可以參考開原始碼的README模組。
樣本
建立外掛程式。
CREATE EXTENSION vector;建立表。
CREATE TABLE t (val vector(3));插入資料。
INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL);建立向量索引。
CREATE INDEX ON t USING ivfflat (val vector_ip_ops) WITH (lists = 1);計算近似向量。
SELECT * FROM t ORDER BY val <#> '[3,3,3]';返回結果如下:
val --------- [1,2,3] [1,1,1] [0,0,0] (3 rows)說明val vector_ip_ops表示需要建立索引的列名為val,並且使用PolarDB PostgreSQL版(相容Oracle)中提供的向量操作符vector_ip_ops來計算向量之間的相似性。該操作符支援向量之間的點積、餘弦相似性、歐幾裡得距離等計算方式。WITH (lists = 1)表示使用的劃分地區數量為1,這意味著所有向量都將被分配到同一個地區中。在實際應用中,劃分地區數量需要根據資料規模和查詢效能進行調整。
相關參考
向量的embedding過程請參考中國內地和國際文本embedding模型輸出。