SELECT ai_embedding('endpoint:my_embedding_model', 'Fresh apple',
JSON '{"dimensions": "768"}') AS embedding;
向量索引使用 HNSW 算法加速检索,创建后自动对写入的数据建立索引
场景 0:使用 ai_embedding 生成向量
问题
如何将文本描述转换为高维向量,用于后续的相似度搜索。
SQL 实现
-- 使用 ai_embedding 将商品描述转为 768 维向量
SELECT
id,
name,
description,
ai_embedding('endpoint:my_embedding_model', description,
JSON '{"dimensions": "768"}') AS embedding
FROM products
WHERE id <= 5;
说明:
ai_embedding
ai_embedding
需要预先配置 Embedding 模型端点(如 OpenAI
text-embedding-3-small
text-embedding-3-small
、阿里云
text-embedding-v4
text-embedding-v4
等)
常见维度:256(轻量)、768(标准)、1024/1536(高精度)
生成向量后可存入 VECTOR 类型列,用于后续相似度搜索
批量生成向量
-- 为存量数据批量生成向量
UPDATE product_embeddings_768
SET embedding = ai_embedding('endpoint:my_embedding_model', description,
JSON '{"dimensions": "768"}')
WHERE embedding IS NULL;
场景 1:语义相似度搜索
问题
给定一个查询向量(如"水果"的 Embedding),找到最相似的商品。
SQL 实现
-- 给定查询文本,使用 ai_embedding 转为向量后检索
-- 实际生产中,查询向量也由 ai_embedding 生成:
-- ai_embedding('endpoint:my_embedding_model', 'fresh sweet fruit')
SELECT
id,
name,
category,
description,
cosine_distance(embedding, ai_embedding('endpoint:my_embedding_model', 'fresh sweet fruit')) AS similarity
FROM product_embeddings
ORDER BY similarity ASC
LIMIT 3;
输出:
id
name
category
description
similarity
1
Apple
Fruit
Fresh red apple...
0.009
2
Banana
Fruit
Ripe yellow banana...
0.652
4
Dog
Animal
Friendly golden retriever...
0.881
关键说明:
cosine_distance
cosine_distance
返回值越小表示越相似(0 = 完全相同,2 = 完全相反)
查询向量由
ai_embedding
ai_embedding
实时生成,与存储向量维度必须一致(如 768 维)
场景 2:多距离函数对比
问题
不同距离度量适用于不同业务场景,需要对比效果。
SQL 实现
-- 对比不同距离度量的效果
-- 查询向量由 ai_embedding 实时生成
SELECT
id,
name,
cosine_distance(embedding, ai_embedding('endpoint:my_embedding_model', 'fresh fruit')) AS cos_dist,
l2_distance(embedding, ai_embedding('endpoint:my_embedding_model', 'fresh fruit')) AS l2_dist,
dot_product(embedding, ai_embedding('endpoint:my_embedding_model', 'fresh fruit')) AS dot_prod
FROM product_embeddings
ORDER BY cos_dist ASC;
输出:
id
name
cos_dist
l2_dist
dot_prod
1
Apple
0.009
0.141
0.74
2
Banana
0.652
0.990
0.26
3
Carrot
0.957
1.273
0.00
4
Dog
0.881
1.086
0.10
5
Elephant
0.949
1.225
0.02
选型建议:
余弦距离: 关注方向而非大小(文本语义、推荐)
欧氏距离: 关注绝对差异(图像特征、空间坐标)
点积: 推荐系统评分(值越大越相关)
场景 3:向量归一化与基准向量
问题
创建零向量作为基准,或计算向量归一化后的相似度。
SQL 实现
-- 创建零向量并计算距离
SELECT
id,
name,
l2_distance(embedding, fill_vector(768, 0.0)) AS dist_to_zero,
l2_norm(embedding) AS vector_length
FROM product_embeddings
ORDER BY dist_to_zero ASC
LIMIT 3;
输出:
id
name
dist_to_zero
vector_length
4
Dog
0.812
0.812
1
Apple
0.906
0.906
2
Banana
0.906
0.906
说明:
l2_distance(v, fill_vector(4, 0.0))
l2_distance(v, fill_vector(4, 0.0))
等价于
l2_norm(v)
l2_norm(v)
。
l2_normalize(v)
l2_normalize(v)
返回归一化后的向量,可用于将点积转为余弦相似度,但向量类型无法直接文本输出。
场景 4:二值化向量与汉明距离
问题
将浮点向量二值化为 0/1 向量,用于快速近似搜索。
SQL 实现
-- 二值化后计算汉明距离(避免直接输出向量列)
SELECT
a.id AS id_a,
a.name AS name_a,
b.id AS id_b,
b.name AS name_b,
hamming_distance(
binary_quantize(a.embedding),
binary_quantize(b.embedding)
) AS hamming_dist
FROM product_embeddings a
JOIN product_embeddings b ON a.id < b.id
ORDER BY hamming_dist ASC
LIMIT 5;
CREATE TABLE product_embeddings (
id BIGINT,
name VARCHAR(100),
embedding VECTOR(768),
INDEX idx_embedding(embedding) USING VECTOR PROPERTIES (
'scalar.type' = 'f32',
'distance.function' = 'cosine_distance'
)
);
方式 2:存量表后建向量索引
-- 先有表和数据,后建索引
CREATE VECTOR INDEX idx_embedding ON TABLE product_embeddings(embedding) PROPERTIES (
'scalar.type' = 'f32',
'distance.function' = 'cosine_distance'
);
-- 存量数据需手动触发构建
BUILD INDEX idx_embedding ON product_embeddings;
验证索引是否生效
-- 查看表上的索引
SHOW INDEX IN product_embeddings;
输出:
index_name
index_type
idx_embedding
vector
关键说明:
建表时声明索引: 插入数据时自动建立索引,无需 BUILD
存量表后建索引: 新建索引只对创建后写入的数据生效,存量数据需执行
BUILD INDEX
BUILD INDEX
补建
向量索引使用 HNSW 算法,适合大规模向量检索
向量索引 + 文本过滤
-- 问题: 向量索引 + WHERE 其他字段过滤会退化到暴力检索
-- 方案 1: 子查询先向量检索,再外层过滤
SELECT id, name, dist FROM (
SELECT id, name, cosine_distance(embedding, query_vec) as dist
FROM product_embeddings
WHERE cosine_distance(embedding, query_vec) < 0.5
ORDER BY dist LIMIT 100
) WHERE name LIKE '%Apple%';
-- 方案 2: 向量索引 + 倒排索引配合使用
SET cz.sql.index.prewhere.enabled=true;
SELECT id, name, cosine_distance(embedding, query_vec) as dist
FROM product_embeddings
WHERE match_regexp(name, '.*Apple.*', map('analyzer', 'keyword'))
AND cosine_distance(embedding, query_vec) < 0.5
ORDER BY dist LIMIT 100;
场景 8:综合实战 — RAG 知识库检索
问题
构建一个简单的 RAG(检索增强生成)知识库检索流程:
将用户查询转为向量
检索 Top K 最相关的文档
按类别过滤结果
SQL 实现
-- RAG 检索流程:
-- 1. 用户查询 → ai_embedding 转为向量
-- 2. 向量检索 → Top K 相关文档
-- 3. 将检索结果 + 原始查询 → LLM 生成回答
SELECT
id,
name,
category,
description,
cosine_distance(embedding, ai_embedding('endpoint:my_embedding_model', 'large land animal')) AS relevance
FROM product_embeddings
WHERE category = 'Animal' -- 可选:按类别过滤
ORDER BY relevance ASC
LIMIT 2;
输出:
id
name
category
relevance
4
Dog
Animal
0.000
5
Elephant
Animal
0.134
RAG 流程说明:
查询文本 → Embedding 模型 → 查询向量
SQL 向量检索 → Top K 相关文档
将检索结果 + 原始查询 → LLM 生成回答
常见问题
1. 向量类型无法直接输出
-- 错误: 直接查询向量列会报错
SELECT embedding FROM product_embeddings;
-- 报错: data type vector(float,4) is not currently supported by textfile writer
-- 正确: 配合距离函数使用,或只输出标量结果
SELECT
id,
name,
cosine_distance(embedding, vector(0.5, 0.5, 0.5, 0.5)) AS dist
FROM product_embeddings;
-- 正确: 二值化后计算距离
SELECT l2_distance(binary_quantize(embedding), binary_quantize(vector(0.5, 0.5, 0.5, 0.5))) AS bin_dist
FROM product_embeddings;
-- 推荐: 先过滤再计算距离
SELECT id, name, cosine_distance(embedding, query_vec) AS dist
FROM product_embeddings
WHERE category = 'Fruit' -- 先缩小范围
ORDER BY dist ASC
LIMIT 3;
-- 不推荐: 全表计算距离后再过滤
SELECT id, name, cosine_distance(embedding, query_vec) AS dist
FROM product_embeddings
ORDER BY dist ASC
LIMIT 100; -- 然后再在应用层过滤 category
-- 推荐: 使用向量索引加速
SET cz.vector.index.search.ef=64; -- 调整探索因子
SELECT id, name, cosine_distance(embedding, query_vec) AS dist
FROM product_embeddings
WHERE cosine_distance(embedding, query_vec) < 0.5 -- 距离阈值触发索引
ORDER BY dist ASC
LIMIT 10;