赞
踩
https://www.postgresql.org/ftp/pgadmin/pgadmin4/
双击 pgadmin4-*-x64.exe 安装文件,选择安装路径,后面安装提示单击 next 就可以了。
打开 pgAdmin,单击 “Add New Server”,
输入 Name,
输入 Connection 信息,
单击 Save,就可以连接这个数据库。
启用扩展(在每个要使用它的数据库中执行一次),
CREATE EXTENSION vector;
创建 3 维向量列,
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
插入向量,
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
通过L2距离获取最近邻居,
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
还支持内积 ( <#> ) 和余弦距离 ( <=> )
注意: <#> 返回负内积,因为 Postgres 仅支持运算符上的 ASC 顺序索引扫描
创建一个带有向量列的新表,
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
或者向现有表添加向量列,
ALTER TABLE items ADD COLUMN embedding vector(3);
插入向量,
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
更新插入向量,
INSERT INTO items (id, embedding) VALUES (1, '[1,2,3]'), (2, '[4,5,6]')
ON CONFLICT (id) DO UPDATE SET embedding = EXCLUDED.embedding;
更新向量,
UPDATE items SET embedding = '[1,2,3]' WHERE id = 1;
删除向量,
DELETE FROM items WHERE id = 1;
获取向量的最近邻,
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
获取一行中最近的邻居,
SELECT * FROM items WHERE id != 1 ORDER BY embedding <-> (SELECT embedding FROM items WHERE id = 1) LIMIT 5;
获取一定距离内的行,
SELECT * FROM items WHERE embedding <-> '[3,1,2]' < 5;
注意:与 ORDER BY 和 LIMIT 结合使用索引
获取距离,
SELECT embedding <-> '[3,1,2]' AS distance FROM items;
对于内积,乘以 -1(因为 <#> 返回负内积),
SELECT (embedding <#> '[3,1,2]') * -1 AS inner_product FROM items;
对于余弦相似度,使用 1 - 余弦距离,
SELECT 1 - (embedding <=> '[3,1,2]') AS cosine_similarity FROM items;
平均向量,
SELECT AVG(embedding) FROM items;
平均向量组,
SELECT category_id, AVG(embedding) FROM items GROUP BY category_id;
默认情况下,pgvector 执行精确的最近邻搜索,从而提供完美的检索率(perfect recall)。
您可以添加索引以使用近似最近邻搜索,这会牺牲一些检索率来换取速度。与典型索引不同,添加近似索引后,您将看到不同的查询结果。
支持的索引类型有:
IVFFlat 索引将向量划分为列表,然后搜索这些列表中最接近查询向量的子集。与 HNSW 相比,它的构建时间更快,使用的内存更少,但查询性能较低(在速度与调用权衡方面)。
实现良好检索率(good recall)的三个关键是:
为您要使用的每个距离函数添加一个索引。
L2距离,
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);
内积(Inner product)
CREATE INDEX ON items USING ivfflat (embedding vector_ip_ops) WITH (lists = 100);
余弦距离,
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
最多可以索引 2,000 个维度的向量。
指定探针数量(默认为1),
SET ivfflat.probes = 10;
较高的值以速度为代价提供更好的检索率,并且可以将其设置为精确最近邻搜索的列表数量(此时规划器将不会使用索引)
在事务内使用 SET LOCAL
将其设置为单个查询,
BEGIN;
SET LOCAL ivfflat.probes = 10;
SELECT ...
COMMIT;
使用 Postgres 12+ 检查索引进度,
SELECT phase, round(100.0 * tuples_done / nullif(tuples_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;
IVFFlat 的阶段是:
注意: % 仅在 loading tuples 阶段填充
HNSW 索引创建多层图。与 IVFFlat 相比,它的构建时间更慢并且使用更多的内存,但具有更好的查询性能(在速度与调用权衡方面)。没有像 IVFFlat 那样的训练步骤,因此可以在表中没有任何数据的情况下创建索引。
为您要使用的每个距离函数添加一个索引。
L2距离,
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);
内积(Inner product),
CREATE INDEX ON items USING hnsw (embedding vector_ip_ops);
余弦距离,
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
最多可以索引 2,000 个维度的向量。
指定 HNSW 参数,
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 16, ef_construction = 64);
指定搜索的动态候选列表的大小(默认为40),
SET hnsw.ef_search = 100;
较高的值提供更好的检索率,但代价是速度。
在事务内使用 SET LOCAL
将其设置为单个查询,
BEGIN;
SET LOCAL hnsw.ef_search = 100;
SELECT ...
COMMIT;
使用 Postgres 12+ 检查索引进度,
SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;
HNSW 的阶段是:
有几种方法可以使用 WHERE 子句对最近邻居查询进行索引,
SELECT * FROM items WHERE category_id = 123 ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
在一个或多个 WHERE 列上创建索引以进行精确搜索,
CREATE INDEX ON items (category_id);
或者向量列上的部分索引以进行近似搜索,
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)
WHERE (category_id = 123);
使用分区对 WHERE 列的许多不同值进行近似搜索,
CREATE TABLE items (embedding vector(3), category_id int) PARTITION BY LIST(category_id);
与 Postgres 全文搜索一起使用以进行混合搜索。
SELECT id, content FROM items, plainto_tsquery('hello search') query
WHERE textsearch @@ query ORDER BY ts_rank_cd(textsearch, query) DESC LIMIT 5;
您可以使用倒数排名融合(Reciprocal Rank Fusion)或交叉编码器(cross-encoder)来组合结果。
使用 EXPLAIN ANALYZE 调试性能。
EXPLAIN ANALYZE SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
要加快没有索引的查询速度,请增加 max_parallel_workers_per_gather
。
SET max_parallel_workers_per_gather = 4;
如果向量标准化为长度 1(如 OpenAI 嵌入),请使用内积以获得最佳性能。
SELECT * FROM items ORDER BY embedding <#> '[3,1,2]' LIMIT 5;
要加快使用 IVFFlat 索引的查询速度,请增加倒排列表的数量(以检索率为代价)。
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 1000);
Q: 一个表中可以存储多少个向量?
A: 默认情况下,Postgres 中非分区表的限制为 32 TB。分区表可以有数千个相同大小的分区。
Q: 支持复制吗?
A: 是的,pgvector 使用预写日志(WAL),它允许复制和时间点恢复。
Q: 如果我想要索引超过 2,000 个维度的向量怎么办?
A: 您现在需要使用降维dimensionality reduction。
Q: 我可以将不同维度的向量存储在同一列中吗?
A: 您可以使用 vector 作为类型(而不是 vector(3) )。
CREATE TABLE embeddings (model_id bigint, item_id bigint, embedding vector, PRIMARY KEY (model_id, item_id));
但是,您只能在具有相同维数的行上创建索引(使用表达式和部分索引):
CREATE INDEX ON embeddings USING hnsw ((embedding::vector(3)) vector_l2_ops) WHERE (model_id = 123);
查询:
SELECT * FROM embeddings WHERE model_id = 123 ORDER BY embedding::vector(3) <-> '[3,1,2]' LIMIT 5;
Q: 我可以更精确地存储向量吗?
A: 您可以使用 double precision[] 或 numeric[] 类型来更精确地存储向量。
CREATE TABLE items (id bigserial PRIMARY KEY, embedding double precision[]);
-- use {} instead of [] for Postgres arrays
INSERT INTO items (embedding) VALUES ('{1,2,3}'), ('{4,5,6}');
(可选)添加检查约束以确保数据可以转换为 vector 类型并具有预期的维度。
ALTER TABLE items ADD CHECK (vector_dims(embedding::vector) = 3);
使用表达式索引来索引(以较低的精度):
CREATE INDEX ON items USING hnsw ((embedding::vector(3)) vector_l2_ops);
查询,
SELECT * FROM items ORDER BY embedding::vector(3) <-> '[3,1,2]' LIMIT 5;
Operator | Description | Added |
---|---|---|
+ | 逐元素加法 | |
- | 逐元素减法 | |
* | 逐元素乘法 | 0.5.0 |
<-> | 欧氏距离 | |
<#> | 负内积 | |
<=> | 余弦距离 |
Function | Description | Added |
---|---|---|
cosine_distance(vector, vector) → double precision | 余弦距离 | |
inner_product(vector, vector) → double precision | 内积 | |
l2_distance(vector, vector) → double precision | 欧氏距离 | |
l1_distance(vector, vector) → double precision | taxicab 距离 | 0.5.0 |
vector_dims(vector) → integer | 维数 | |
vector_norm(vector) → double precision | 欧几里得范数 |
Function | Description | Added |
---|---|---|
avg(vector) → vector | 平均的 | |
sum(vector) → vector | 和 | 0.5.0 |
完结!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。