跳转至

6.8.7 TOPN 查询优化

TOPN 查询是指下面这种 ORDER BY LIMIT 查询,在日志检索等明细查询场景中很常见, Doris 会自动对这种类型的查询进行优化。

SQL
1
SELECT * FROM tablex WHERE xxx ORDER BY c1,c2 ... LIMIT n

1 TOPN 查询优化的优化点

  1. 执行过程中动态对排序列构建范围过滤条件(比如 c1 >= 10000 ),读数据时自动带上前面的条件,利用 Zonemap 索引过滤到一些数据甚至文件。

  2. 如果排序字段 c1c2 正好是 Table Key 的前缀,则更进一步优化,读数据的时候只用读数据文件的头部或者尾部 n 行。

  3. SELECT * 延迟物化,读数据和排序过程中只读排序列不读其它列,得到符合条件的行号后,再去读那 n 行需要的全部列数据,大幅减少读取和排序的列。

2 TOPN 查询优化的限制

  1. 只能用于 Duplicate 表和 Unique MOW 表,因为 MOR 表用这个优化可能有结果错误。

  2. 对于过大的 n ,优化内存消耗会很大,所以超过 topn_opt_limit_threshold Session 变量的 n 不会使用优化。

3 配置参数和查询分析

下面两个参数都是 Session Variable ,可以针对某个 SQL 或者全局设置。

  1. topn_opt_limit_thresholdLIMIT n 小于这个值才会有优化,默认值 1024 ,将它设置为 0 可以关闭 TOPN 查询优化。

  2. enable_two_phase_read_opt ,是否开启优化 3 ,默认为 true ,可以调为 false 关闭这个优化。

  3. topn_filter_ratioLIMIT n 和表总数据的比率,默认值 0.5 ,表示 LIMIT 数量多于表中数据的一半则不生成 filter

3.1 检查 TOPN 查询优化是否启用

explain SQL 拿到 query plan 可以确认这个 sql 是否启用 TOPN 查询优化,以下面的为例:

  • TOPN OPT 代表有优化 1

  • VOlapScanNode 下面有 SORT LIMIT 代表有优化 2

  • OPT TWO PHRASE 代表有优化 3

SQL
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  1:VTOP-N(137)
  |  order by: @timestamp18 DESC
  |  TOPN OPT
  |  OPT TWO PHASE
  |  offset: 0
  |  limit: 10
  |  distribute expr lists: applicationName5
  |  
  0:VOlapScanNode(106)
     TABLE: log_db.log_core_all_no_index(log_core_all_no_index), PREAGGREGATION: ON
     SORT INFO:
          @timestamp18
     SORT LIMIT: 10
     TOPN OPT:1
     PREDICATES: ZYCFC-TRACE-ID4 like '%flowId-1720055220933%'
     partitions=1/8 (p20240704), tablets=250/250, tabletList=1727094,1727096,1727098 ...
     cardinality=345472780, avgRowSize=0.0, numNodes=1
     pushAggOp=NONE

3.2 检查 TOPN 查询优化执行时是否有效果

首先,可以将 topn_filter_ratio 设置为 0 关闭 TOPN 查询优化,对比开启和关闭优化的 SQL 执行时间。

开启 TOPN 查询优化后,在 Query Profile 中搜索 RuntimePredicate ,关注下面几个指标:

  • RowsZonemapRuntimePredicateFiltered 这个代表过滤掉的行数,越大越好

  • NumSegmentFiltered 这个代表过滤掉的数据文件个数,越大越好

  • BlockConditionsFilteredZonemapRuntimePredicateTime 代表过滤数据的耗时,越小越好

注意, 2.0.3 之前的版本中 RuntimePredicate 的指标未独立,可以通过 Zonamap 指标大致观察。

SQL
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    SegmentIterator:
          -  BitmapIndexFilterTimer:  46.54us
          -  BlockConditionsFilteredBloomFilterTime:  10.352us
          -  BlockConditionsFilteredDictTime:  7.299us
          -  BlockConditionsFilteredTime:  202.23ms
          -  BlockConditionsFilteredZonemapRuntimePredicateTime:  0ns
          -  BlockConditionsFilteredZonemapTime:  402.917ms
          -  BlockInitSeekCount:  399
          -  BlockInitSeekTime:  11.309ms
          -  BlockInitTime:  215.59ms
          -  BlockLoadTime:  7s567ms
          -  BlocksLoad:  392.97K  (392970)
          -  CachedPagesNum:  0
          -  CollectIteratorMergeTime:  0ns
          -  CollectIteratorNormalTime:  0ns
          -  CompressedBytesRead:  29.76  MB
          -  DecompressorTimer:  427.713ms
          -  ExprFilterEvalTime:  3s930ms
          -  FirstReadSeekCount:  392.921K  (392921)
          -  FirstReadSeekTime:  528.287ms
          -  FirstReadTime:  1s134ms
          -  IOTimer:  51.286ms
          -  InvertedIndexFilterTime:  49.457us
          -  InvertedIndexQueryBitmapCopyTime:  0ns
          -  InvertedIndexQueryBitmapOpTime:  0ns
          -  InvertedIndexQueryCacheHit:  0
          -  InvertedIndexQueryCacheMiss:  0
          -  InvertedIndexQueryTime:  0ns
          -  InvertedIndexSearcherOpenTime:  0ns
          -  InvertedIndexSearcherSearchTime:  0ns
          -  LazyReadSeekCount:  0
          -  LazyReadSeekTime:  0ns
          -  LazyReadTime:  106.952us
          -  NumSegmentFiltered:  0
          -  NumSegmentTotal:  50
          -  OutputColumnTime:  61.987ms
          -  OutputIndexResultColumnTimer:  12.345ms
          -  RawRowsRead:  3.929151M  (3929151)
          -  RowsBitmapIndexFiltered:  0
          -  RowsBloomFilterFiltered:  0
          -  RowsConditionsFiltered:  6.38976M  (6389760)
          -  RowsDictFiltered:  0
          -  RowsInvertedIndexFiltered:  0
          -  RowsKeyRangeFiltered:  0
          -  RowsShortCircuitPredFiltered:  0
          -  RowsShortCircuitPredInput:  0
          -  RowsStatsFiltered:  6.38976M  (6389760)
          -  RowsVectorPredFiltered:  0
          -  RowsVectorPredInput:  0
          -  RowsZonemapRuntimePredicateFiltered:  6.38976M  (6389760)
          -  SecondReadTime:  0ns
          -  ShortPredEvalTime:  0ns
          -  TotalPagesNum:  2.301K  (2301)
          -  UncompressedBytesRead:  137.99  MB
          -  VectorPredEvalTime:  0ns