9.3 查询性能优化:让命中更快 本节摘要:查询慢了不要瞎调参数,先诊断:慢查询日志圈出嫌疑人,画像接口拆解耗时构成,指标定位瓶颈层(IO、CPU、线程池)。诊断之后是五刀:filter 化吃缓存、限制扇出、深分页换游标、字段瘦身、索引与分片重规划。本节把第 3、5、8 章的零件组装成一套可复用的提速方法论。 慢下来的时刻 一、诊断三步:先找嫌疑人,再验伤,后定位 第一步开慢查询日志,把"慢"变成名单: 超过五百毫秒的查询写进慢日志,带着完整的请求体与分片级耗时——名单有了。第二步对头号嫌疑人做画像,看时间花在哪一段: 第三步看节点指标:线程池拒绝数涨说明查询排队长(并发超载)、IO 等待高说明在扫冷数据(缓存不命中)、CPU 高而 IO 低说明在算(脚本、深归并、大 bool)。
本节摘要:查询慢了不要瞎调参数,先诊断:慢查询日志圈出嫌疑人,画像接口拆解耗时构成,指标定位瓶颈层(IO、CPU、线程池)。诊断之后是五刀:filter 化吃缓存、限制扇出、深分页换游标、字段瘦身、索引与分片重规划。本节把第 3、5、8 章的零件组装成一套可复用的提速方法论。
第一步开慢查询日志,把"慢"变成名单:
PUT tickets/_settings { "index.search.slowlog.threshold.query.warn": "2s", "index.search.slowlog.threshold.query.info": "500ms", "index.search.slowlog.threshold.fetch.warn": "1s" }
超过五百毫秒的查询写进慢日志,带着完整的请求体与分片级耗时——名单有了。第二步对头号嫌疑人做画像,看时间花在哪一段:
GET tickets/_search { "profile": true, "query": { "match": { "title": "退款" } } }
profile 响应(节选): "query" 段 title 的 rewrite 与 collect 各占多少毫秒 "fetch" 段 source 加载与高亮各占多少 直接指出 瓶颈在查询期还是取回期
第三步看节点指标:线程池拒绝数涨说明查询排队长(并发超载)、IO 等待高说明在扫冷数据(缓存不命中)、CPU 高而 IO 低说明在算(脚本、深归并、大 bool)。三步下来,慢的层与量都有数,才轮到动刀。

第一刀:filter 化与缓存。 5.2 讲过 filter 上下文不算分、结果可缓存——同条件重复查询近乎零成本。检查所有"匹不匹配"型条件(状态、时间范围、租户、标签)是否还留在 must 里,搬进 filter 是零风险高回报的第一刀。第二刀:限制扇出。 一次查询扇出到所有涉及分片(5.1 的两阶段),扇出越少归并越轻:带 routing 只查相关分片(写入侧同 routing 前提下)、时间范围查询只点名相关日期索引(按天滚动的索引名做过滤)、禁用无谓的跨索引通配。第三刀:翻页换姿势。 深翻页的候选爆炸(5.3 的推导)改成游标方案;导出场景检查有没有人拿 from 加 size 一万一页硬翻——这是集群公敌。第四刀:字段与响应瘦身。 取回期占比高时,源过滤只取要展示的字段、高亮字段限量、size 别虚高;列表页三十条足够,别一次取两百"备用"。第五刀:索引重规划。 前四刀无效说明瓶颈在结构:冷热数据混在一个索引里互相拖累——按时间拆索引、冷索引进生命周期管理迁到低配存储;分片过小过碎或过大过沉,回到 8.2 的规划原则重排。第五刀成本最高(要重建迁移),所以放最后。
背景:运营反馈工单搜索偶发五六秒,高峰尤甚;慢日志一开,名单里三条查询反复出现。操作:画像显示取回期占七成——响应里带着完整 _source(每条三 KB)加五个字段的高亮;同时查询期 bool 里挂着租户过滤与时间范围的 must。动刀:源过滤只取列表页四字段、高亮限两字段;must 里的两个条件搬进 filter;size 从五十降到二十。结果:三条查询全部回到两百毫秒内,集群取回线程池排队消失。解读:两刀都是"减法"——少取、少算、少扇出,优化查询最常见的形态不是加什么,而是减什么。变式:改完仍慢的第四条查询走的是跨三十天通配搜索,拆成按天索引名列表后(查询端生成最近七天),扇出减七成,也回到可接受区间。
常见坑:跳过诊断直接抄网上的调优清单——加大缓存、改线程数、换打分模式。参数调优是最后一厘米,结构与查询形态才是主体;顺序反了,等于不问伤在哪就开药。
关键直觉:慢查询的账单分三栏——查得多(扇出广)、算得多(评分与脚本)、搬得多(源与高亮)。诊断就是算清三栏各占多少,优化就是砍最贵的一栏。
| 考核点 | 达标标准 |
|---|---|
| 诊断三步 | 慢日志列名单、画像分期、指标定位层的顺序与产出 |
| 账单三栏 | 查得多、算得多、搬得多分别对应什么症状 |
| 五刀排序 | 按风险成本排出五刀顺序,并给每刀配适用前提 |
| 症状速查 | 取回期高、查询期高、排队拒绝、IO 等待各自的刀法 |
| 缓存前提 | 说出过滤化的生效条件与缓存失效的诱因 |
| 参数调优位次 | 解释为什么改参数排在结构优化与查询改造之后 |
慢查询日志是诊断的原料库,两条设置就能开工:
PUT tickets/_settings { "index.search.slowlog.threshold.query.warn": "1s", "index.search.slowlog.threshold.fetch.warn": "200ms" }
超过一秒的查询期与两百毫秒的取回期会分列两本日志,每条带请求体原文。攒一天名单,按耗时排序取前三条下刀——诊断流程的第一步就此落地,第五章的画像参数则在每条下刀前给出分期证据。