GET products/_search
{"query": {"wildcard": {"title": {"value": "手机*"}}}}
GET products/_search
{"query": {"match_phrase": {"title": "手机"}}}
商品搜索写成 wildcard *手机*,单次查询 12 秒,节点 CPU 打到 100%,慢日志里全是这条。去掉前面的星号后 40ms 就返回了。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:前置通配没法用倒排表的词典序定位,只能把每个词条逐个扫一遍再比对。词条上百万时,一次查询就是全词表扫描。后置通配还能按前缀缩小范围,前置等于放弃索引。
「wildcard 前置通配」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
处理上按这个顺序:去掉前缀星号 改成 prefix 或 match_phrase;需要后缀匹配的字段单独建 ngram 分词;必须模糊匹配的场景放到独立节点 别和在线查询混用;用 profile 确认重写后扫了多少词条。
确认没问题再收工,查询耗时从 12 秒降到 100ms 以内,profile 里没有整段词条扫描。
