前提条件
- 确保已安装pgvector扩展。
- 确保已在PostgreSQL数据库中创建了带有向量字段的表。
示例
假设有一个包含向量的表items
,表结构如下:
CREATE TABLE items (
id serial PRIMARY KEY,
vector vector(3)
);
插入样本数据
INSERT INTO items (vector) VALUES
('[0.1, 0.2, 0.3]'),
('[0.4, 0.5, 0.6]'),
('[0.7, 0.8, 0.9]'),
('[0.2, 0.1, 0.0]'),
('[0.5, 0.4, 0.3]');
查询相似度
假设你有一个查询向量[0.1, 0.2, 0.3]
,你想从这些样本中找到与其相似的前3个向量,并且设定相似度阈值为0.8。
SELECT id, vector, vector <=> '[0.1, 0.2, 0.3]' AS distance
FROM items
WHERE vector <=> '[0.1, 0.2, 0.3]' < 0.8
ORDER BY vector <=> '[0.1, 0.2, 0.3]'
LIMIT 3;
解释
vector <=> '[0.1, 0.2, 0.3]'
计算向量之间的距离。WHERE vector <=> '[0.1, 0.2, 0.3]' < 0.8
过滤出距离小于0.8的向量。ORDER BY vector <=> '[0.1, 0.2, 0.3]'
根据距离从小到大排序。LIMIT 3
限制返回的结果数量为3。
使用Python进行批量查询
如果要用Python进行批量查询,可以使用psycopg2
库来执行上述SQL查询:
import psycopg2
def batch_query_similar_vectors(query_vector, threshold, top_k):
conn = psycopg2.connect(
dbname="your_database",
user="your_user",
password="your_password",
host="your_host",
port="your_port"
)
cur = conn.cursor()
query = """
SELECT id, vector, vector <=> %s AS distance
FROM items
WHERE vector <=> %s < %s
ORDER BY vector <=> %s
LIMIT %s;
"""
cur.execute(query, (query_vector, query_vector, threshold, query_vector, top_k))
results = cur.fetchall()
cur.close()
conn.close()
return results
query_vector = '[0.1, 0.2, 0.3]'
threshold = 0.8
top_k = 3
results = batch_query_similar_vectors(query_vector, threshold, top_k)
for result in results:
print(result)
这样,你就可以根据相似度阈值批量查询并返回前K个结果。
在pgvector中,向量索引是一种用于加速向量相似度搜索的技术。pgvector支持使用几种不同类型的索引来优化向量查询速度,其中最常见的是IVFFlat索引。以下是关于向量索引的详细介绍:
IVFFlat 索引
IVFFlat (Inverted File with Flat quantization) 是一种常用于向量检索的索引类型,它将向量分成若干簇,并在每个簇内进行快速线性扫描。以下是创建和使用IVFFlat索引的步骤:
创建IVFFlat索引
-
创建表格并插入数据:
首先,创建一个包含向量数据的表格,并插入数据。CREATE TABLE items ( id serial PRIMARY KEY, vector vector(3) ); INSERT INTO items (vector) VALUES ('[0.1, 0.2, 0.3]'), ('[0.4, 0.5, 0.6]'), ('[0.7, 0.8, 0.9]'), ('[0.2, 0.1, 0.0]'), ('[0.5, 0.4, 0.3]');
-
创建IVFFlat索引:
使用以下SQL命令创建IVFFlat索引。这里的vector_l2_ops
表示使用L2距离度量。CREATE INDEX ON items USING ivfflat (vector vector_l2_ops) WITH (lists = 100);
在这个命令中,
lists
参数指定了簇的数量,通常根据数据量和查询性能进行调整。
使用索引进行查询
创建索引后,可以使用向量相似度搜索进行查询。例如,要查找与查询向量[0.1, 0.2, 0.3]
相似的前3个结果,可以使用以下查询:
SELECT id, vector, vector <=> '[0.1, 0.2, 0.3]' AS distance
FROM items
ORDER BY vector <=> '[0.1, 0.2, 0.3]'
LIMIT 3;
在有索引的情况下,这个查询会比没有索引的情况快很多,尤其是在数据量较大的情况下。
HNSW 索引
另一种常用的向量索引是HNSW (Hierarchical Navigable Small World)。HNSW索引基于小世界图理论,具有高效的查询性能和构建速度。
创建HNSW索引
CREATE INDEX ON items USING hnsw (vector) WITH (m = 16, ef_construction = 200);
在这个命令中,m
和ef_construction
是HNSW算法的参数,分别控制图的稀疏程度和索引构建时的搜索深度。
使用向量索引的好处
- 查询速度快: 向量索引显著提高了大规模向量数据的查询速度。
- 可扩展性: 支持大规模数据的高效检索。
- 灵活性: 支持不同类型的距离度量(如L2距离、内积等)。
索引参数调整
不同的索引类型和参数设置会对性能产生不同影响。根据数据规模和查询需求,可以调整参数(如IVFFlat中的lists
或HNSW中的m
和ef_construction
)以优化性能。
示例:IVFFlat索引与批量查询
假设你有一个包含5000个向量的查询列表,可以使用创建的IVFFlat索引加速查询:
from concurrent.futures import ThreadPoolExecutor
import psycopg2
def query_similar_vectors_batch(query_vector_batch, threshold, top_k):
conn = psycopg2.connect(
dbname="your_database",
user="your_user",
password="your_password",
host="your_host",
port="your_port"
)
cur = conn.cursor()
results = []
for query_vector in query_vector_batch:
query = """
SELECT id, vector, vector <=> %s AS distance
FROM items
WHERE vector <=> %s < %s
ORDER BY vector <=> %s
LIMIT %s;
"""
cur.execute(query, (query_vector, query_vector, threshold, query_vector, top_k))
results.extend(cur.fetchall())
cur.close()
conn.close()
return results
def batch_query_similar_vectors(query_vectors, threshold, top_k, batch_size):
with ThreadPoolExecutor(max_workers=10) as executor:
futures = [
executor.submit(query_similar_vectors_batch, query_vectors[i:i + batch_size], threshold, top_k)
for i in range(0, len(query_vectors), batch_size)
]
results = []
for future in futures:
results.extend(future.result())
return results
query_vectors = [...] # 5000个长文本向量列表
threshold = 0.8
top_k = 3
batch_size = 500 # 每批次处理500个向量
results = batch_query_similar_vectors(query_vectors, threshold, top_k, batch_size)
for result in results:
print(result)
通过创建和使用向量索引,可以显著提高pgvector在大规模数据集上的查询性能。
如果优先考虑文本召回率,即希望在相似度查询中尽可能多地召回相关的文本,那么使用HNSW(Hierarchical Navigable Small World)索引通常是一个较好的选择。HNSW索引在保持高查询速度的同时,能够提供较高的召回率。
HNSW索引
HNSW索引基于小世界图理论,通过构建多层图结构,使得在大规模数据集中能够高效地进行近似最近邻搜索。HNSW索引的关键参数有两个:
M
: 控制每个节点的最大连接数。较高的值通常会提高召回率,但也会增加索引构建和查询时间。ef_construction
: 控制索引构建时的搜索深度。较高的值通常会提高召回率和构建时间。
创建HNSW索引
以下是创建HNSW索引的示例:
CREATE INDEX ON items USING hnsw (vector) WITH (m = 16, ef_construction = 200);
调整参数以优化召回率
为了优化召回率,可以适当增加M
和ef_construction
的值。例如:
CREATE INDEX ON items USING hnsw (vector) WITH (m = 32, ef_construction = 500);
查询示例
创建HNSW索引后,可以使用向量相似度搜索进行查询。例如,要查找与查询向量[0.1, 0.2, 0.3]
相似的前3个结果,可以使用以下查询:
SELECT id, vector, vector <=> '[0.1, 0.2, 0.3]' AS distance
FROM items
ORDER BY vector <=> '[0.1, 0.2, 0.3]'
LIMIT 3;
使用Python进行批量查询
同样可以使用Python进行批量查询,并行处理以提高效率:
from concurrent.futures import ThreadPoolExecutor
import psycopg2
def query_similar_vectors_batch(query_vector_batch, threshold, top_k):
conn = psycopg2.connect(
dbname="your_database",
user="your_user",
password="your_password",
host="your_host",
port="your_port"
)
cur = conn.cursor()
results = []
for query_vector in query_vector_batch:
query = """
SELECT id, vector, vector <=> %s AS distance
FROM items
WHERE vector <=> %s < %s
ORDER BY vector <=> %s
LIMIT %s;
"""
cur.execute(query, (query_vector, query_vector, threshold, query_vector, top_k))
results.extend(cur.fetchall())
cur.close()
conn.close()
return results
def batch_query_similar_vectors(query_vectors, threshold, top_k, batch_size):
with ThreadPoolExecutor(max_workers=10) as executor:
futures = [
executor.submit(query_similar_vectors_batch, query_vectors[i:i + batch_size], threshold, top_k)
for i in range(0, len(query_vectors), batch_size)
]
results = []
for future in futures:
results.extend(future.result())
return results
query_vectors = [...] # 5000个长文本向量列表
threshold = 0.8
top_k = 3
batch_size = 500 # 每批次处理500个向量
results = batch_query_similar_vectors(query_vectors, threshold, top_k, batch_size)
for result in results:
print(result)
通过使用HNSW索引并调整其参数,可以在保证查询效率的同时提高召回率,从而更好地满足你的需求。