TOPN 查询优化
更新时间:2025-05-29
TOPN 查询是指下面这种 ORDER BY LIMIT 查询,在日志检索等明细查询场景中很常见,PALO 会自动对这种类型的查询进行优化。
SQL
1SELECT * FROM tablex WHERE xxx ORDER BY c1,c2 ... LIMIT n
TOPN 查询优化的优化点
- 执行过程中动态对排序列构建范围过滤条件(比如 c1 >= 10000),读数据时自动带上前面的条件,利用 Zonemap 索引过滤掉一些数据甚至文件。
- 如果排序字段 c1,c2 正好是 Table Key 的前缀,则更进一步优化,读数据的时候只用读数据文件的头部或者尾部 n 行。
- SELECT * 延迟物化,读数据和排序过程中只读排序列不读其它列,得到符合条件的行号后,再去读那 n 行需要的全部列数据,大幅减少读取和排序的列。
TOPN 查询优化的限制
- 只能用于 Duplicate 表和 Unique MOW 表,因为 MOR 表用这个优化可能有结果错误。
- 对于过大的
n
,优化内存消耗会很大,所以超过topn_opt_limit_threshold
Session 变量的n
不会使用优化。
配置参数和查询分析
下面两个参数都是 Session Variable,可以针对某个 SQL 或者全局设置。
topn_opt_limit_threshold
,LIMIT n 小于这个值才会有优化,默认值 1024,将它设置为 0 可以关闭 TOPN 查询优化。enable_two_phase_read_opt
,是否开启优化 3,默认为 true,可以调为 false 关闭这个优化。topn_filter_ratio
,LIMIT n 和表总数据的比率,默认值 0.5,表示 LIMIT 数量多于表中数据的一半则不生成 filter。
检查 TOPN 查询优化是否启用
explain SQL 拿到 query plan 可以确认这个 sql 是否启用 TOPN 查询优化,以下面的为例:
- TOPN OPT 代表有优化 1
- VOlapScanNode 下面有 SORT LIMIT 代表有优化 2
- OPT TWO PHASE 代表有优化 3
SQL
1 1:VTOP-N(137)
2 | order by: @timestamp18 DESC
3 | TOPN OPT
4 | OPT TWO PHASE
5 | offset: 0
6 | limit: 10
7 | distribute expr lists: applicationName5
8 |
9 0:VOlapScanNode(106)
10 TABLE: log_db.log_core_all_no_index(log_core_all_no_index), PREAGGREGATION: ON
11 SORT INFO:
12 @timestamp18
13 SORT LIMIT: 10
14 TOPN OPT:1
15 PREDICATES: ZYCFC-TRACE-ID4 like '%flowId-1720055220933%'
16 partitions=1/8 (p20240704), tablets=250/250, tabletList=1727094,1727096,1727098 ...
17 cardinality=345472780, avgRowSize=0.0, numNodes=1
18 pushAggOp=NONE
检查 TOPN 查询优化执行时是否有效果
首先,可以将 topn_opt_limit_threshold
设置为 0 关闭 TOPN 查询优化,对比开启和关闭优化的 SQL 执行时间。
开启 TOPN 查询优化后,在 Query Profile 中搜索 RuntimePredicate,关注下面几个指标:
RowsZonemapRuntimePredicateFiltered
这个代表过滤掉的行数,越大越好NumSegmentFiltered
这个代表过滤掉的数据文件个数,越大越好BlockConditionsFilteredZonemapRuntimePredicateTime
代表过滤数据的耗时,越小越好
注意,2.0.3 之前的版本中 RuntimePredicate 的指标未独立,可以通过 Zonamap 指标大致观察。
SQL
1 SegmentIterator:
2 - BitmapIndexFilterTimer: 46.54us
3 - BlockConditionsFilteredBloomFilterTime: 10.352us
4 - BlockConditionsFilteredDictTime: 7.299us
5 - BlockConditionsFilteredTime: 202.23ms
6 - BlockConditionsFilteredZonemapRuntimePredicateTime: 0ns
7 - BlockConditionsFilteredZonemapTime: 402.917ms
8 - BlockInitSeekCount: 399
9 - BlockInitSeekTime: 11.309ms
10 - BlockInitTime: 215.59ms
11 - BlockLoadTime: 7s567ms
12 - BlocksLoad: 392.97K (392970)
13 - CachedPagesNum: 0
14 - CollectIteratorMergeTime: 0ns
15 - CollectIteratorNormalTime: 0ns
16 - CompressedBytesRead: 29.76 MB
17 - DecompressorTimer: 427.713ms
18 - ExprFilterEvalTime: 3s930ms
19 - FirstReadSeekCount: 392.921K (392921)
20 - FirstReadSeekTime: 528.287ms
21 - FirstReadTime: 1s134ms
22 - IOTimer: 51.286ms
23 - InvertedIndexFilterTime: 49.457us
24 - InvertedIndexQueryBitmapCopyTime: 0ns
25 - InvertedIndexQueryBitmapOpTime: 0ns
26 - InvertedIndexQueryCacheHit: 0
27 - InvertedIndexQueryCacheMiss: 0
28 - InvertedIndexQueryTime: 0ns
29 - InvertedIndexSearcherOpenTime: 0ns
30 - InvertedIndexSearcherSearchTime: 0ns
31 - LazyReadSeekCount: 0
32 - LazyReadSeekTime: 0ns
33 - LazyReadTime: 106.952us
34 - NumSegmentFiltered: 0
35 - NumSegmentTotal: 50
36 - OutputColumnTime: 61.987ms
37 - OutputIndexResultColumnTimer: 12.345ms
38 - RawRowsRead: 3.929151M (3929151)
39 - RowsBitmapIndexFiltered: 0
40 - RowsBloomFilterFiltered: 0
41 - RowsConditionsFiltered: 6.38976M (6389760)
42 - RowsDictFiltered: 0
43 - RowsInvertedIndexFiltered: 0
44 - RowsKeyRangeFiltered: 0
45 - RowsShortCircuitPredFiltered: 0
46 - RowsShortCircuitPredInput: 0
47 - RowsStatsFiltered: 6.38976M (6389760)
48 - RowsVectorPredFiltered: 0
49 - RowsVectorPredInput: 0
50 - RowsZonemapRuntimePredicateFiltered: 6.38976M (6389760)
51 - SecondReadTime: 0ns
52 - ShortPredEvalTime: 0ns
53 - TotalPagesNum: 2.301K (2301)
54 - UncompressedBytesRead: 137.99 MB
55 - VectorPredEvalTime: 0ns