报错是这么冒出来的。Milvus 2.4 里 60 万条文档,title 字段建了 INVERTED 索引,查询写 title like '退款%',响应要 1.8 秒,get_query_segment_info 显示所有 segment 都被扫;换成 title == '退款流程' 只要 40 毫秒,环境是 3 节点集群。

中间走过弯路,把「查询同时带向量检索,like 被放到后过滤阶段执行」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。like 前缀在 Milvus 里不走倒排索引,等价于逐行匹配。少数情况下是字段是 VARCHAR 但 max_length 给到 65535,索引没真正生效。

还有一种情况,索引建在另一个 partition,查询没命中那个分区。

先确认 title 上到底有没有倒排索引

python -c "from pymilvus import Collection;c=Collection('docs');print([i.params for i in c.indexes])"

再往下用 describe 看字段的 max_length

python -c "from pymilvus import Collection;c=Collection('docs');print([f.params for f in c.schema.fields if f.name=='title'])"

接着把标题改写成前缀 token 字段并用 term 查询

python -c "from pymilvus import Collection;c=Collection('docs');print(c.query(expr=\"title_prefix == '退款'\", output_fields=['id'], limit=5))"

等前面都确认过,再对同一条件做耗时对比再决定是否换写法

python -c "import time;from pymilvus import Collection;c=Collection('docs');s=time.time();c.query(expr=\"title like '退款%'\", output_fields=['id'], limit=5);print(time.time()-s)"

怎么算真的好了,看的是同一批现象。前缀条件改成等值或 term 查询后耗时降到 50 毫秒以内,命中条数与 like 前缀的结果一致,segment 扫描数明显下降。

容易忽略的是,like 在 Milvus 里只保证语义正确,不保证走索引;高频前缀过滤应该在入库时额外写一个前缀字段,用 term 查,而不是指望倒排去优化 like。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189