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)

执行一个查询:

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

在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 # 物化列的耗时。

BufferPool

BufferPool:

调试方式

参见官网

JoinReorder

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

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

原理

查询时一旦涉及到多表联合,那么联合的顺序对整个联合查询的性能影响很大。假设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'}

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

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)

开启之后的执行计划,可以看到开启前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)

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'];

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

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

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

查看索引

语法:

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

或者

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

示例,展示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)

删除索引

语法:

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

示例:

DROP INDEX IF EXISTS table_bitmap ON table1;

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"
);

查看布隆过滤器索引

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)

修改布隆过滤器索引

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

删除过滤器索引

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

合理设置分桶分区数

  • 一个表的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命令查看,结果除以副本数,即表的数据量。

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值