• Doris学习笔记之优化


    查看QueryProfile

    利用查询执行的统计结果,可以更好地帮助我们了解Doris的执行情况,并有针对性地进行相应的调试调优工作。FE将查询计划拆分成Fragment下发到BE执行任务,BE在执行Fragment时记录了运行状态的统计值,并将统计信息输出到日志中。FE也可以通过开关将各个Fragment统计值进行搜集,并在FE的web页面上打印结果。

    使用方式

    开启profile:

    mysql> set enable_profile=true;
    Query OK, 0 rows affected (0.00 sec)
    
    • 1
    • 2

    执行一个查询:

    mysql> SELECT t1 FROM test JOIN test2 where test.t1 = test2.t2;
    +------+
    | t1   |
    +------+
    |    3 |
    |    4 |
    +------+
    2 rows in set (0.16 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在FE的web界面上查看http://scentos:8030/QueryProfile:
    在这里插入图片描述
    点击QueryID:
    在这里插入图片描述

    参数说明

    Fragment

    在这里插入图片描述

    BlockMgr

    在这里插入图片描述

    DataStreamSender

    在这里插入图片描述

    ODBC_TABLE_SINK

    在这里插入图片描述

    EXCHANGE_NODE

    在这里插入图片描述

    SORT_NODE

    在这里插入图片描述
    在这里插入图片描述

    AGGREGATION_NODE

    在这里插入图片描述

    HASH_JOIN_NODE

    在这里插入图片描述

    CROSS_JOIN_NODE

    在这里插入图片描述

    UNION_NODE

    在这里插入图片描述

    ANALYTIC_EVAL_NODE

    在这里插入图片描述

    OLAP_SCAN_NODE

    OLAP_SCAN_NODE节点负责具体的数据扫描任务,一个OLAP_SCAN_NODE会生成一个或多个OlapScanner ,每个Scanner线程负责扫描部分数据,查询中的部分或全部谓词条件会推送给OLAP_SCAN_NODE。这些谓词条件中一部分会继续下推给存储引擎,以便利用存储引擎的索引进行数据过滤。另一部分会保留在OLAP_SCAN_NODE 中,用于过滤从存储引擎中返回的数据。OLAP_SCAN_NODE 节点的Profile通常用于分析数据扫描的效率,依据调用关系分为OLAP_SCAN_NODE、OlapScanner、SegmentIterator三层:

    OLAP_SCAN_NODE (id=0):(Active:  2.185ms,  %  non-child:  1.66%)
    - BytesRead: 95.00 B # 从数据文件中读取到的数据量。假设读取到了是10个32位整型,则数据量为10 * 4B = 40 Bytes。这个数据仅表示数据在内存中全展开的大小,并不代表实际的IO大小。
    - NumDiskAccess: 1 # 该ScanNode节点涉及到的磁盘数量。
    - NumScanners: 6 # 该ScanNode生成的 Scanner 数量。
    - PeakMemoryUsage: 0.00 # 查询时内存使用的峰值,暂未使用
    - RowsRead: 2 # 从存储引擎返回到Scanner的行数,不包括经Scanner过滤的行数。
    - RowsReturned: 2 # 从ScanNode返回给上层节点的行数。
    - RowsReturnedRate: 915 # RowsReturned/ActiveTime
    - TabletCount : 2 # 该 ScanNode 涉及的Tablet数量。
    - TotalReadThroughput: 0.0 /sec # BytesRead 除以该节点运行的总时间(从Open到Close),对于IO受限的查询,接近磁盘的总吞吐量。
    - ScannerBatchWaitTime: 1.773ms # 用于统计transfer线程等待scaner线程返回rowbatch的时间。
    - ScannerWorkerWaitTime: 2.182ms # 用于统计scanner thread等待线程池中可用工作线程的时间。
    OlapScanner(test):
    - BlockConvertTime: 561us # 将向量化Block转换为行结构的RowBlock的耗时,向量化Block在V1中为VectorizedRowBatch,V2中为RowBlockV2。
    - BlockFetchTime: 166.723us # Rowset Reader获取Block的时间。
    - ReaderInitTime: 7.722ms # OlapScanner初始化 Reader的时间,V1中包括组建MergeHeap的时间,V2中包括生成各级Iterator并读取第一组Block的时间。
    - RowsDelFiltered: 0 # 包括根据Tablet中存在的Delete信息过滤掉的行数,以及unique key模型下对被标记的删除行过滤的行数。
    - RowsPushedCondFiltered: 0 # 根据传递下推的谓词过滤掉的条件,比如Join计算中从BuildTable传递给ProbeTable的条件。该数值不准确,因为如果过滤效果差,就不再过滤了。
    - ScanTime: 4.953us # 从ScanNode返回给上层节点的时间。
    - ShowHintsTime_V1: 0ns # V2中无意义,V1中读取部分数据来进行ScanRange 的切分。
    SegmentIterator:
    - BitmapIndexFilterTimer: 293ns # 利用bitmap索引过滤数据的耗时。
    - BlockLoadTime: 159.716us # SegmentReader(V1) 或SegmentIterator(V2) 获取block的时间。
    - BlockSeekCount: 19 # 读取Segment时进行block seek的次数。
    - BlockSeekTime: 61.545us # 读取Segment时进行block seek的耗时。
    - BlocksLoad: 2 # 读取Block的数量
    - CachedPagesNum: 4 # 仅V2中,当开启PageCache后,命中Cache的Page数量。
    - CompressedBytesRead: 107.00B # V1中,从文件中读取的解压前的数据大小,V2中,读取到的没有命中PageCache的Page的压缩前的大小。
    - DecompressorTimer: 0ns # 数据解压耗时。
    - IOTimer: 1.888us # 实际从操作系统读取数据的IO时间。
    - IndexLoadTime_V1: 0ns # 仅V1 中,读取Index Stream的耗时。
    - NumSegmentFiltered: 0 # 在生成Segment Iterator时,通过列统计信息和查询条件,完全过滤掉的Segment数量。
    - NumSegmentTotal: 6 # 查询涉及的所有Segment数量。
    - RawRowsRead: 2 # 存储引擎中读取的原始行数,详情见下文。
    - RowsBitmapIndexFiltered: 0 # 仅V2中,通过Bitmap索引过滤掉的行数。
    - RowsBloomFilterFiltered: 0 # 仅V2中,通过BloomFilter索引过滤掉的行数。
    - RowsKeyRangeFiltered: 10 # 仅V2中,通过SortkeyIndex索引过滤掉的行数。
    - RowsStatsFiltered: 0 # V2中,通过ZoneMap索引过滤掉的行数,包含删除条件;V1中还包含通过BloomFilter过滤掉的行数。
    - RowsConditionsFiltered: 0 # 仅V2中,通过各种列索引过滤掉的行数。
    - RowsVectorPredFiltered: 0 # 通过向量化条件过滤操作过滤掉的行数。
    - TotalPagesNum: 6 # 仅V2中,读取的总Page数量。
    - UncompressedBytesRead: 67.00B # V1中为读取的数据文件解压后的大小(如果文件无需解压,则直接统计文件大小);V2中,仅统计未命中PageCache的Page解压后的大小(如果Page无需解压,直接统计Page大小)
    - VectorPredEvalTime: 18.369us # 向量化条件过滤操作的耗时。
    - ShortPredEvalTime: 0ns # 短路谓词过滤操作的耗时。
    - PredColumnReadTime: 0ns # 谓词列读取的耗时。
    - LazyReadTime: 0ns # 非谓词列读取的耗时。
    - OutputColumnTime: 0ns # 物化列的耗时。
    
    • 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

    BufferPool

    BufferPool:

    调试方式

    参见官网

    JoinReorder

    Join重排序功能可以通过代价模型自动帮助调整SQL中的join顺序,以得到最优的Join效率,可通过会话变量开启:

    mysql> set enable_cost_based_join_reorder=true;
    Query OK, 0 rows affected (0.00 sec)
    
    • 1
    • 2

    原理

    查询时一旦涉及到多表联合,那么联合的顺序对整个联合查询的性能影响很大。假设abc三张表联合,如下图所示,左边是a表先和b表做join,中间结果有2000行,而后再和c表联合:
    在这里插入图片描述
    再看右图,把联合的顺序进行了调整:a表先和c联合,生成中间结果100行,再和b表联合。最终的结果一样,但生成中间结果数量有20倍的差距,这是一个很大的性能差异。

    Doris目前支持基于规则的Join重排序算法,逻辑如下:

    1. 让大表尽量join小表,生成尽可能小的中间结果;
    2. 把有条件的join表往前放;
    3. hash联合的优先级高于NestLoop联合,因为前者本身就比后者快很多。

    示例

    准备表和数据:

    mysql> create table test3 like test;
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> insert into test3 values(3),(2),(1),(4),(5),(6),(7);
    Query OK, 7 rows affected (0.09 sec)
    {'label':'insert_ddc7d95f80924970-bca7e71913af4202', 'status':'VISIBLE', 'txnId':'3004'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    联合重排序开启前的执行计划:

    mysql> explain graph SELECT test.t1 FROM test JOIN test2 on test.t1 = test2.t2 join test3 on test.t1 = test3.t1;
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Explain String                                                                                                                                                                                  |
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |                                      ┌───────────────┐                                                                                                                                          |
    |[7: ResultSink]|
    |[Fragment: 3]|
    |                                      │RESULT SINK    │                                                                                                                                          |
    |                                      └───────────────┘                                                                                                                                          |
    ||
    ||
    |                                       ┌─────────────┐                                                                                                                                           |
    |[7: EXCHANGE]|
    |[Fragment: 3]|
    |                                       └─────────────┘                                                                                                                                           |
    ||
    ||
    |                                    ┌───────────────────┐                                                                                                                                        |
    |[7: DataStreamSink]|
    |[Fragment: 0]|
    |                                    │STREAM DATA SINK   │                                                                                                                                        |
    |                                    │  EXCHANGE ID: 07|
    |                                    │  UNPARTITIONED    │                                                                                                                                        |
    |                                    └───────────────────┘                                                                                                                                        |
    ||
    ||
    |                           ┌────────────────────────────────────┐                                                                                                                                |
    |[4: HASH JOIN]|
    |[Fragment: 0]|
    |join op: INNER JOIN (BUCKET_SHUFFLE)|
    |                           └────────────────────────────────────┘                                                                                                                                |
    |                            ┌─────────────────┴───────────────────────────┐                                                                                                                      |
    |                            │                                             │                                                                                                                      |
    |         ┌────────────────────────────────────┐                    ┌─────────────┐                                                                                                               |
    |[2: HASH JOIN]                      │                    │[6: EXCHANGE]|
    |[Fragment: 0]                       │                    │[Fragment: 0]|
    |join op: INNER JOIN (BUCKET_SHUFFLE)│                    └─────────────┘                                                                                                               |
    |         └────────────────────────────────────┘                           │                                                                                                                      |
    |          ┌─────────────────┴─────────┐                                   │                                                                                                                      |
    |          │                           │                  ┌─────────────────────────────────┐                                                                                                     |
    | ┌─────────────────┐           ┌─────────────┐           │[6: DataStreamSink]|
    |[0: OlapScanNode]│           │[5: EXCHANGE]│           │[Fragment: 2]|
    |[Fragment: 0]    │           │[Fragment: 0]│           │STREAM DATA SINK                 │                                                                                                     |
    |TABLE: test      │           └─────────────┘           │  EXCHANGE ID: 06|
    | └─────────────────┘                  │                  │  BUCKET_SHFFULE_HASH_PARTITIONED│                                                                                                     |
    |                                      │                  └─────────────────────────────────┘                                                                                                     |
    |                     ┌─────────────────────────────────┐                  │                                                                                                                      |
    |[5: DataStreamSink]              │                  │                                                                                                                      |
    |[Fragment: 1]                    │         ┌─────────────────┐                                                                                                             |
    |                     │STREAM DATA SINK                 │         │[3: OlapScanNode]|
    |                     │  EXCHANGE ID: 05                │         │[Fragment: 2]|
    |                     │  BUCKET_SHFFULE_HASH_PARTITIONED│         │TABLE: test3     │                                                                                                             |
    |                     └─────────────────────────────────┘         └─────────────────┘                                                                                                             |
    ||
    ||
    |                             ┌─────────────────┐                                                                                                                                                 |
    |[1: OlapScanNode]|
    |[Fragment: 1]|
    |TABLE: test2     │                                                                                                                                                 |
    |                             └─────────────────┘                                                                                                                                                 |
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    56 rows in set (0.00 sec)
    
    • 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
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    开启之后的执行计划,可以看到开启前test先和test2联合,开启后test先和test3联合:

    mysql> explain graph SELECT test.t1 FROM test JOIN test2 on test.t1 = test2.t2 join test3 on test.t1 = test3.t1;
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Explain String                                                                                                                                                                                  |
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |                                      ┌───────────────┐                                                                                                                                          |
    |[8: ResultSink]|
    |[Fragment: 3]|
    |                                      │RESULT SINK    │                                                                                                                                          |
    |                                      └───────────────┘                                                                                                                                          |
    ||
    ||
    |                                       ┌─────────────┐                                                                                                                                           |
    |[8: EXCHANGE]|
    |[Fragment: 3]|
    |                                       └─────────────┘                                                                                                                                           |
    ||
    ||
    |                                    ┌───────────────────┐                                                                                                                                        |
    |[8: DataStreamSink]|
    |[Fragment: 0]|
    |                                    │STREAM DATA SINK   │                                                                                                                                        |
    |                                    │  EXCHANGE ID: 08|
    |                                    │  UNPARTITIONED    │                                                                                                                                        |
    |                                    └───────────────────┘                                                                                                                                        |
    ||
    ||
    |                           ┌────────────────────────────────────┐                                                                                                                                |
    |[5: HASH JOIN]|
    |[Fragment: 0]|
    |join op: INNER JOIN (BUCKET_SHUFFLE)|
    |                           └────────────────────────────────────┘                                                                                                                                |
    |                            ┌─────────────────┴───────────────────────────┐                                                                                                                      |
    |                            │                                             │                                                                                                                      |
    |         ┌────────────────────────────────────┐                    ┌─────────────┐                                                                                                               |
    |[4: HASH JOIN]                      │                    │[7: EXCHANGE]|
    |[Fragment: 0]                       │                    │[Fragment: 0]|
    |join op: INNER JOIN (BUCKET_SHUFFLE)│                    └─────────────┘                                                                                                               |
    |         └────────────────────────────────────┘                           │                                                                                                                      |
    |          ┌─────────────────┴─────────┐                                   │                                                                                                                      |
    |          │                           │                  ┌─────────────────────────────────┐                                                                                                     |
    | ┌─────────────────┐           ┌─────────────┐           │[7: DataStreamSink]|
    |[0: OlapScanNode]│           │[6: EXCHANGE]│           │[Fragment: 2]|
    |[Fragment: 0]    │           │[Fragment: 0]│           │STREAM DATA SINK                 │                                                                                                     |
    |TABLE: test      │           └─────────────┘           │  EXCHANGE ID: 07|
    | └─────────────────┘                  │                  │  BUCKET_SHFFULE_HASH_PARTITIONED│                                                                                                     |
    |                                      │                  └─────────────────────────────────┘                                                                                                     |
    |                     ┌─────────────────────────────────┐                  │                                                                                                                      |
    |[6: DataStreamSink]              │                  │                                                                                                                      |
    |[Fragment: 1]                    │         ┌─────────────────┐                                                                                                             |
    |                     │STREAM DATA SINK                 │         │[1: OlapScanNode]|
    |                     │  EXCHANGE ID: 06                │         │[Fragment: 2]|
    |                     │  BUCKET_SHFFULE_HASH_PARTITIONED│         │TABLE: test2     │                                                                                                             |
    |                     └─────────────────────────────────┘         └─────────────────┘                                                                                                             |
    ||
    ||
    |                             ┌─────────────────┐                                                                                                                                                 |
    |[2: OlapScanNode]|
    |[Fragment: 1]|
    |TABLE: test3     │                                                                                                                                                 |
    |                             └─────────────────┘                                                                                                                                                 |
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    56 rows in set (0.01 sec)
    
    • 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
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    Join的优化原则

    • 在做Join的时候,要尽量选择同类型或者简单类型的列,同类型的话就减少它的数据Cast,简单类型本身Joi 计算就很快。
    • 尽量选择Key列进行Join, 原因前面在Runtime Filter的时候也介绍了,Key列在延迟物化上能起到一个比较好的效果。
    • 大表之间的Join ,尽量让它Co-location ,因为大表之间的网络开销是很大的,如果需要去做Shuffle 的话,代价是很高的。
    • 合理的使用Runtime Filter,它在Join过滤率高的场景下效果是非常显著的。但是它并不是万灵药,而是有一定副作用的,所以需要根据具体的SQL的粒度做开关。
    • 涉及到多表Join 的时候,需要去判断Join 的合理性。尽量保证左表为大表,右表为小表,然后Hash Join会优于Nest Loop Join。必要的时可以通过SQL Rewrite,利用Hint去调整Join的顺序。
      在这里插入图片描述

    导入导出性能优化

    在提交LOAD作业前,先执行set enable_profile=true打开会话变量,然后提交导入作业。待导入作业完成后,可以在FE的web 页面的Queries标签中查看到导入作业的Profile,这个Profile可以帮助分析导入作业的运行状态。当前只有作业成功执行后,才能查看Profile。

    FE配置

    系统配置

    FE的系统配置,可在fe.conf中修改:
    在这里插入图片描述

    broker相关

    在这里插入图片描述
    本次导入并发数 = Math.min(源文件大小/最小处理量,最大并发数,当前BE节点个数);
    本次导入单个BE的处理量 = 源文件大小/本次导入的并发数。

    StreamLoad相关

    在这里插入图片描述

    导出相关

    在这里插入图片描述
    在这里插入图片描述

    BE配置

    以下配置属于BE配置,可通过be.conf修改:
    在这里插入图片描述

    StreamLoad相关

    在这里插入图片描述
    在这里插入图片描述

    性能分析

    导入过程中的查询超时,建议先看监控,grafana上的数据。比如是否导入占用了过多的IO或者cpu等,导致了相互影响,再逐步根据pprof + 代码分析。

    Broker导入大文件

    由于单个导入BE的最大处理量默认为3G,因此超过3G的待导入文件需要通过调整BrokerLoad的导入参数来实现导入。

    修改fe.conf中的配置

    根据当前BE个数和原始文件的大小修改单个BE的最大扫描量和最大并发数:

    max_broker_concurrency = BE个数

    当前导入任务单个BE处理的数据量 = 原始文件大小 / max_broker_concurrency
    max_bytes_per_broker_scanner >= 当前导入任务单个BE处理的数据量
    比如一个100G的文件,集群的BE数为10:

    max_broker_concurrency = 10
    max_bytes_per_broker_scanner >= 10G = 100G / 10
    修改后,所有的BE会并发处理导入任务,每个BE处理原始文件的一部分。注意,上述两个FE配置均为系统配置,修改后会作用于所有的BrokerLoead任务。

    合理设置timeout时间。

    可以在创建导入的时候自定义任务的超时时间:

    单个BE处理数据量/最慢导入速度(MB/s)>=timeout时间>=单个BE处理数据量/10M/s

    比如一个100G的文件,集群的BE数为10:timeout >= 1000s = (10G / 10)M/s
    若计算出来的超时时间超过系统默认的导入最大超时时间4h,不推荐通过直接将导入最大超时时间改为最大来解决问题,最好是通过切分待导入文件并且分多次来导入,因为单次导入超过4h的话,导入失败的重试时间成本太高、

    评估导入最大数据量

    可通过如下公式计算出Doris集群期望的最大导入文件数据量:

    期望最大导入文件数据量 = 14400s * 10M/s * BE个数

    比如,集群的BE数为10:期望最大导入文件数据量 = 14400s * 10M/s * 10 = 1440000M ≈ 1440G

    一般环境可能达不到10M/s的速度,所以建议超过500G的文件都先进行文件切分,再导入

    Bitmap索引

    创建索引

    用户可以通过创建位图索引加速查询,创建语法:

    CREATE INDEX [IF NOT EXISTS] index_name ON table_name (column [, ...],) [USING BITMAP] [COMMENT'balabala'];
    
    • 1

    注意,位图索引只能在单列上创建。

    示例,在table1的siteid上创建位图索引:

    mysql> CREATE INDEX table_bitmap ON table1 (siteid) USING BITMAP COMMENT 'table1_bitmap_index';
    Query OK, 0 rows affected (0.05 sec)
    
    • 1
    • 2

    查看索引

    语法:

    SHOW INDEX[ES] FROM [db_name.]table_name [FROM database];
    
    • 1

    或者

    SHOW KEY[S] FROM [db_name.]table_name [FROM database];
    
    • 1

    示例,展示table1上的索引:

    mysql> SHOW INDEX FROM table1;
    +-----------------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------------------+
    | Table                       | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment             |
    +-----------------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------------------+
    | default_cluster:test.table1 |            | table_bitmap |              | siteid      |           |             |          |        |      | BITMAP     | table1_bitmap_index |
    +-----------------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------------------+
    1 row in set (0.00 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    删除索引

    语法:

    DROP INDEX [IF EXISTS] index_name ON [db_name.]table_name;
    
    • 1

    示例:

    DROP INDEX IF EXISTS table_bitmap ON table1;
    
    • 1

    BloomFilter索引

    Doris的布隆过滤器索引是在建表时指定,或者通过表的alter操作完成。布隆过滤器本质上是一种位图结构,用于快速判断一个给定的值是否在一个集合中,会产生小概率的误判。布隆过滤器索引是以block为粒度创建的,每个block中,指定列的值作为一个集合生成一个布隆过滤器索引条目,用于在查询时快速过滤不满足条件的数据。

    指定布隆过滤器索引

    建表时指定布隆过滤器索引:

    CREATE TABLE IF NOT EXISTS sale_detail_bloom (
        sale_date date NOT NULL COMMENT "销售时间",
        customer_id int NOT NULL COMMENT "客户编号",
        saler_id int NOT NULL COMMENT "销售员",
        sku_id int NOT NULL COMMENT "商品编号",
        category_id int NOT NULL COMMENT "商品分类",
        sale_count int NOT NULL COMMENT "销售数量",
        sale_price DECIMAL(12,2) NOT NULL COMMENT "单价",
        sale_amt DECIMAL(20,2) COMMENT "销售总金额"
    )
    Duplicate KEY(sale_date, customer_id,saler_id,sku_id,category_id)
    PARTITION BY RANGE(sale_date)
    (
        PARTITION P_202111 VALUES [('2021-11-01'), ('2021-12-01'))
    )
    DISTRIBUTED BY HASH(saler_id) BUCKETS 10
    PROPERTIES (
        "replication_num" = "1",
        "bloom_filter_columns"="saler_id,category_id",
        "dynamic_partition.enable" = "true",
        "dynamic_partition.time_unit" = "MONTH",
        "dynamic_partition.time_zone" = "Asia/Shanghai",
        "dynamic_partition.start" = "-2147483648",
        "dynamic_partition.end" = "2",
        "dynamic_partition.prefix" = "P_",
        "dynamic_partition.replication_num" = "3",
        "dynamic_partition.buckets" = "3",
        "storage_medium" = "SSD"
    );
    
    • 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

    查看布隆过滤器索引

    mysql> SHOW CREATE TABLE sale_detail_bloom;
    +-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table             | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
    +-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | sale_detail_bloom | CREATE TABLE `sale_detail_bloom` (
      `sale_date` date NOT NULL COMMENT "销售时间",
      `customer_id` int(11) NOT NULL COMMENT "客户编号",
      `saler_id` int(11) NOT NULL COMMENT "销售员",
      `sku_id` int(11) NOT NULL COMMENT "商品编号",
      `category_id` int(11) NOT NULL COMMENT "商品分类",
      `sale_count` int(11) NOT NULL COMMENT "销售数量",
      `sale_price` decimal(12, 2) NOT NULL COMMENT "单价",
      `sale_amt` decimal(20, 2) NULL COMMENT "销售总金额"
    ) ENGINE=OLAP
    DUPLICATE KEY(`sale_date`, `customer_id`, `saler_id`, `sku_id`, `category_id`)
    COMMENT "OLAP"
    PARTITION BY RANGE(`sale_date`)
    (PARTITION P_202111 VALUES [('2021-11-01'), ('2021-12-01')))
    DISTRIBUTED BY HASH(`saler_id`) BUCKETS 10
    PROPERTIES (
    "replication_allocation" = "tag.location.default: 1",
    "bloom_filter_columns" = "category_id, saler_id",
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "MONTH",
    "dynamic_partition.time_zone" = "Asia/Shanghai",
    "dynamic_partition.start" = "-2147483648",
    "dynamic_partition.end" = "2",
    "dynamic_partition.prefix" = "P_",
    "dynamic_partition.replication_allocation" = "tag.location.default: 3",
    "dynamic_partition.buckets" = "3",
    "dynamic_partition.create_history_partition" = "false",
    "dynamic_partition.history_partition_num" = "-1",
    "dynamic_partition.hot_partition_num" = "0",
    "dynamic_partition.reserved_history_periods" = "NULL",
    "dynamic_partition.start_day_of_month" = "1",
    "in_memory" = "false",
    "storage_format" = "V2"
    ); |
    +-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.01 sec)
    
    • 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

    修改布隆过滤器索引

    mysql> ALTER TABLE sale_detail_bloom SET ("bloom_filter_columns" = "customer_id,sku_id");
    Query OK, 0 rows affected (0.01 sec)
    
    • 1
    • 2

    删除过滤器索引

    mysql> ALTER TABLE sale_detail_bloom SET ("bloom_filter_columns"= "");
    Query OK, 0 rows affected (0.00 sec)
    
    • 1
    • 2

    合理设置分桶分区数

    • 一个表的Tablet总数量等于 (Partition num * Bucket num)。
    • 一个表的Tablet数量,在不考虑扩容的情况下,推荐略多于整个集群的磁盘数量。
    • 单个Tablet的数据量理论上没有上下界,但建议在1G - 10G的范围内。如果单个Tablet 数据量过小,则数据的聚合效果不佳,且元数据管理压力大。如果数据量过大,则不利于副本的迁移、补齐,且会增加Schema Change或者Rollup操作失败重试的代价(这些操作失败重试的粒度是Tablet)。
    • 当Tablet的数据量原则和数量原则冲突时,建议优先考虑数据量原则。
    • 在建表时,每个分区的Bucket数量统一指定。但是在动态增加分区时ADD PARTITION,可以单独指定新分区的Bucket数量。可以利用这个功能方便的应对数据缩小或膨胀。
    • 一个Partition的Bucket数量一旦指定,不可更改。所以在确定Bucket数量时,需要预先考虑集群扩容的情况。比如当前只有3台host,每台host有1块盘。如果Bucket的数量只设置为3或更小,那么后期即使再增加机器,也不能提高并发度。
    • 举一些例子:假设在有10台BE,每台BE一块磁盘。如果一个表总大小为 500MB,则可以考虑4-8个分片;5GB:8-16 个;50GB:32 个;500GB:建议分区,每个分区大小在50GB左右,每个分区16-32个分片;5TB:建议分区,每个分区大小在50GB左右,每个分区16-32个分片。

    注:表的数据量可以通过show data命令查看,结果除以副本数,即表的数据量。

  • 相关阅读:
    前后端开发环境下载,java web前后端分离项目所有环境下载
    伦敦金开户需要多少资金,有开户条件吗?
    c++-程序基本框架
    257. 二叉树的所有路径
    水果店圈子:水果店水果都去哪进货,水果店进货怎么找货源
    单片机实验--单片机IO口实验
    强化学习之父Richard Sutton:通往AGI的另一种可能
    游戏企业通关秘籍:华为云游戏全场景能力,开发+部署+运营“关关难过关关过”...
    【大数据】Spark使用大全:下载安装、RDD操作、JAVA编程、SQL
    Android View绘制基础
  • 原文地址:https://blog.csdn.net/qq_37475168/article/details/126190287