2026年11月2日,我修改了博客文章标题的重复判定逻辑。此前,系统通过Python读取所有已保存的嵌入向量并计算相似度;此次则改为利用 MariaDB 11.8+ 的向量索引,仅获取相近的标题候选项。

在此过程中,需要注意SQL的排序表达式。ORDER BY 1 - VEC_DISTANCE_COSINE(...) DESC 可以表达相似度顺序,但如果将距离函数包裹在计算式中,可能无法利用向量索引。官方文档建议直接按距离函数或其别名进行升序排列,并结合使用 LIMIT。MariaDB官方文档

因此,检索基于距离进行,而仅在Python中将返回值转换为 similarity = 1 - distance。以下是精简后的SQLAlchemy绑定核心示例。:query_vector 中传递的是由同一嵌入模型生成的向量的JSON字符串。

sql
SELECT translation_id,
       VEC_DISTANCE_COSINE(embedding, VEC_FromText(:query_vector)) AS distance
FROM title_vectors
ORDER BY VEC_DISTANCE_COSINE(embedding, VEC_FromText(:query_vector)) ASC
LIMIT 10;

该示例的前提是 embedding 中存在 DISTANCE=cosine 向量索引。如果构建索引时的距离方式与检索函数不一致,则索引将不会被使用。VEC_DISTANCE_COSINE文档

此次变更还添加了集成测试,用于检查 EXPLAIN 的结果中的 key 是否为预期的向量索引。性能提升幅度需要单独测量,但从代码中可以确认,检索路径已从原先通过Python读取所有向量缩减为候选项查询。

如果已创建索引,请务必确认查询是否真正使用了该索引。即使通过表达式表示相同的顺序,执行计划也并不一定相同。