*Redis FT.PROFILE 命令
FT.PROFILE 用于分析 RediSearch 查询的执行计划,帮助诊断查询性能问题和优化搜索语句。
*语法
FT.PROFILE index_name [SEARCH | AGGREGATE] [NOCONTENT] [LIMIT offset num] query [WITHCOUNT] [VERBATIM]
*参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| index_name | String | 是 | 索引名称 |
| SEARCH / AGGREGATE | 关键字 | 是 | 分析 SEARCH 或 AGGREGATE 查询 |
| query | String | 是 | 查询表达式 |
| NOCONTENT | Flag | 否 | 不返回文档内容(SEARCH 模式) |
| LIMIT offset num | Integer | 否 | 分页参数(SEARCH 模式) |
| WITHCOUNT | Flag | 否 | 返回精确计数(AGGREGATE 模式) |
| VERBATIM | Flag | 否 | 禁用词干提取和扩展(SEARCH 模式) |
*返回值
返回一个数组,包含两部分: 1. 查询结果:与 FT.SEARCH 或 FT.AGGREGATE 相同的正常结果 2. 性能分析信息: - Total profile time: 总执行时间(纳秒) - Parsing time: 查询解析时间(纳秒) - Pipeline creation time: 管道创建时间(纳秒) - Warning: 警告信息(如查询未命中索引) - Iterators profile: 迭代器分析信息,包含每个迭代器的: - Type: 迭代器类型(UNION, INTERSECT, TAG, TEXT, NUMERIC, EMPTY, etc.) - Time: 迭代器耗时(纳秒) - Counter: 调用次数 - Child iterators: 子迭代器信息
*时间复杂度
取决于查询本身的时间复杂度。FT.PROFILE 增加了轻微的分析开销。
*示例
*分析 SEARCH 查询
> FT.PROFILE myIndex SEARCH query "hello world"
1) 1) 1) "1"
2) "doc:100"
3) 1) "title"
2) "hello world example"
2) 1) "Total profile time"
2) "1.234567"
3) "Parsing time"
4) "0.123456"
5) "Pipeline creation time"
6) "0.234567"
7) "Iterators profile"
8) 1) "Type"
2) "INTERSECT"
3) "Time"
4) "0.5"
5) "Counter"
6) "1"
7) "Child iterators"
8) 1) 1) "Type"
2) "TEXT"
3) "Term"
4) "hello"
5) "Time"
6) "0.2"
7) "Counter"
8) "1"
2) 1) "Type"
2) "TEXT"
3) "Term"
4) "world"
5) "Time"
6) "0.15"
7) "Counter"
8) "1"
*分析 AGGREGATE 查询
> FT.PROFILE myIndex AGGREGATE query "*" GROUPBY 1 @category REDUCE COUNT 0 AS count
1) 1) 1) "category"
2) "electronics"
3) "count"
4) "500"
2) 1) "Total profile time"
2) "2.5"
3) "Parsing time"
4) "0.1"
5) "Pipeline creation time"
6) "0.3"
7) "Result processors profile"
8) 1) "Type"
2) "Index"
3) "Time"
4) "0.8"
5) "Counter"
6) "1000"
7) "Type"
8) "Grouper"
9) "Time"
10) "0.5"
11) "Counter"
12) "500"
13) "Type"
14) "Sorter"
15) "Time"
16) "0.2"
17) "Counter"
18) "500"
*带 NOCONTENT 的快速分析
> FT.PROFILE myIndex SEARCH NOCONTENT query "redis search"
1) 1) 1) "1"
2) "doc:200"
2) 1) "2"
2) "doc:201"
2) 1) "Total profile time"
2) "0.5"
3) "Parsing time"
4) "0.05"
5) "Iterators profile"
6) ...
*常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| Unknown index name | 索引不存在 | 检查索引名称拼写或先创建索引 |
| Syntax error: SEARCH or AGGREGATE required | 缺少模式关键字 | 必须指定 SEARCH 或 AGGREGATE |
| Syntax error: No query text | 缺少查询内容 | 提供 query 参数 |
| Warning: query has no profile | 查询无法被分析 | 检查查询语法是否完整 |
*最佳实践
- 在性能问题排查时优先使用 FT.PROFILE 代替 FT.SEARCH/FT.AGGREGATE
- 重点关注
Iterators profile中的Time和Counter,识别耗时最长的迭代器 - 若
Warning提示查询未使用索引,考虑优化查询语句或索引字段 - 对比优化前后的 FT.PROFILE 输出,验证性能改进效果
- 使用
NOCONTENT模式减少分析时的数据传输开销 - 分析复杂的 AGGREGATE 查询时,关注各 Result Processor 的耗时分布
*FAQ
Q1: FT.PROFILE 会影响线上性能吗? A: 影响很小,但建议在非高峰时段或测试环境进行详细的性能分析。FT.PROFILE 本身增加了纳秒级别的分析开销。
Q2: 如何解读 Iterators profile 中的 Type 字段? A: 常见类型包括:TEXT(文本匹配)、TAG(标签匹配)、NUMERIC(数值范围)、UNION(并集)、INTERSECT(交集)、EMPTY(无结果)。若看到复杂的嵌套 INTERSECT 或 UNION,说明查询正在合并多个条件,可能是优化点。
Q3: 为什么 FT.PROFILE 的结果会多一层数组? A: 第一级数组是正常查询结果,第二级是性能分析数据。需要分别解析以获取查询结果和性能指标。
Q4: FT.PROFILE 和 EXPLAIN 有什么区别? A: FT.PROFILE 返回实际执行时间和性能统计,而 EXPLAIN 仅返回查询执行计划(理论分析)。FT.PROFILE 更适合性能诊断。