18 个回答
使用bitmap的时候需要注意他是有2个意思,分别是:
1、Bitmap 索引(用于快速过滤)
1、Bitmap 索引(用于快速过滤)
适合那种枚举值很少、重复度高的列(比如性别、省份、状态)。它为每个值创建一个比特位数组,用 0 和 1 表示某行数据是否是这个值。这样,当进行等值查询时,可以直接对 bitmap 进行高效的位运算,速度极快。特别适合对表中靠后的、无法用前缀索引的列进行过滤。2、Bitmap 去重(用于精确计算 UV)这是精准计算唯一值(比如日活用户数 UV)的利器。Doris 提供了 BITMAP数据类型和 BITMAP_UNION聚合函数。你可以把用户 ID 这类信息转换成 bitmap 存储,计算 UV 时直接对 bitmap 进行合并统计,又快又准。发布于:5天前 IP属地:四川省
使用物化视图的预计算功能,比如你总要看每个门店的销售总额,每次都去扫描亿级明细数据再 sum 太慢了。那就可以创建一个物化视图,提前把 store_id和对应的 sum(amount)算好存起来。下次再查,直接从这个小小的结果集里取数,瞬间出结果。
发布于:5天前 IP属地:四川省
常规的 join 操作,经常需要把数据在不同机器间来回传输,网络开销很大。使用Colocation Join:把要关联的数据放一起,join起来就非常方便了,实现的话就是:让需要经常关联的表(比如订单表和明细表)使用相同的分桶键和分桶数量,这样相同键值的数据就会被分配到同一个 BE 节点的同一个桶里。当进行 join 时,计算直接在本地完成,基本没有网络传输,速度自然快。注意这里有几个限制条件:
1、表的分桶列、分桶数量必须完全一致。
2、副本数也得一致。说白了,得是“门当户对”的表才能用这个功能。发布于:5天前 IP属地:四川省
建表的时候,你指定一列或者几列作为排序键(Sort Key),数据在存的时候就会按照这个顺序排好队。比如你按 sku_id和 store_id排了序,当你查 where sku_id=10 and store_id='BJ01'的时候,Doris 就能像查字典一样,用二分法快速定位到那部分数据,不用全表扫描。这速度一下子就上来了。
发布于:5天前 IP属地:四川省
这里需要注意几个点:
1、排序列得放在建表语句里靠前的位置。
2、别贪多,排序列不是越多越好,太多会影响数据导入速度。通常前面一两列就能精准定位了,后面的列作用不大。
3、顺序有讲究。把区分度高、经常被用来查询的列放前面。比如 store_id如果单独查询的概率和 sku_id+store_id组合查询差不多,那可以考虑把 store_id放第一位。如果排序顺序不能满足所有查询场景,还有个法宝——RollUp 表(现在叫物化视图更强大)。可以理解为给原表另建一个按不同顺序排队的数据副本,专门服务另一种查询模式。发布于:5天前 IP属地:四川省
利用workload group实现资源隔离,提升集群资源利用率,示例如下:
-- 创建资源组
CREATE WORKLOAD GROUP "analytics"
PROPERTIES (
"cpu_limit" = "50%",
"memory_limit" = "30%",
"concurrency_limit" = "10"
);
-- 创建资源组
CREATE WORKLOAD GROUP "etl"
PROPERTIES (
"cpu_limit" = "30%",
"memory_limit" = "50%",
"concurrency_limit" = "5"
);
-- 将用户绑定到资源组
CREATEUSER'analyst'@'%' IDENTIFIED BY'password'
PROPERTIES ("workload_group" = "analytics");
CREATEUSER'etl_user'@'%' IDENTIFIED BY'password'
PROPERTIES ("workload_group" = "etl");发布于:3个月前 (08-14) IP属地:四川省
这里可以结合查询优先级进行管理,示例如下:
-- 设置查询优先级
SET QUERY_PRIORITY = 'HIGH';
-- 在资源组中配置优先级
ALTER WORKLOAD GROUP "analytics"
SET PROPERTIES ("query_priority" = "HIGH");发布于:3个月前 (08-14) IP属地:四川省
利用ToN的查询进行提前终止和堆排序优化,示例如下:
-- 启用 TopN 优化
SET enable_topn_opt = true;
-- 调整 TopN 缓存大小
SET topn_cache_size = 1024;
-- 传统方式(全排序后取前N)
SELECT * FROM orders ORDER BY amount DESC LIMIT 10;
-- 优化方式(使用 TopN 算子)
EXPLAIN
SELECT * FROM orders ORDER BY amount DESC LIMIT 10;发布于:3个月前 (08-14) IP属地:四川省
利用行缓存提高查询效率,配置如下:
-- 启用行缓存
SET enable_row_cache = true;
-- 调整行缓存大小(默认 2MB)
SET row_cache_mem_limit = "50MB";
-- 查看缓存命中率
SHOW BACKENDS;
-- 然后访问 BE 的 metrics 页面查看 row_cache_hit_rate查询示例如下:-- 创建 Unique 模型表(自动行存)
CREATE TABLE orders (
order_id BIGINT,
user_id BIGINT,
amount DECIMAL(10,2),
status VARCHAR(20)
) UNIQUE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 32;
-- 查询自动使用行存优化
SELECT * FROM orders WHERE order_id = 1000001;发布于:3个月前 (08-14) IP属地:四川省
如果不要求去重结果非常精准的话,可以考虑使用hll近似去重,示例如下:
-- 创建表时使用 HLL 类型
CREATE TABLE page_views (
page_id INT,
view_date DATE,
users HLL HLL_UNION
) AGGREGATE KEY(page_id, view_date);
-- 数据导入
INSERT INTO page_views VALUES
(1001, '2023-10-01', hll_hash(1001)),
(1001, '2023-10-01', hll_hash(1002)),
(1001, '2023-10-01', hll_hash(1001));
-- 查询近似去重结果
SELECT
page_id,
view_date,
hll_union_agg(users) AS approx_unique_users
FROM page_views
GROUPBY page_id, view_date;注意使用的时候需要对误差进行控制,示例如下:-- 设置 HLL 精度(默认 12,精度越高误差越小)
SET hll_precision = 16;发布于:3个月前 (08-14) IP属地:四川省
查询的时候使用bitmap进行精准去重,示例代码如下:
-- 创建表时使用 BITMAP 类型
CREATE TABLE user_actions (
user_id BIGINT,
action_date DATE,
actions BITMAP BITMAP_UNION
) AGGREGATE KEY(user_id, action_date);
-- 数据导入
INSERT INTO user_actions VALUES
(1001, '2023-10-01', to_bitmap(101)),
(1001, '2023-10-01', to_bitmap(102)),
(1001, '2023-10-01', to_bitmap(101));
-- 查询去重结果
SELECT
user_id,
action_date,
bitmap_union_count(actions) AS unique_actions
FROM user_actions
GROUPBY user_id, action_date;发布于:3个月前 (08-14) IP属地:四川省
bitmap去重去比比使用distinct去重要快5-10倍左右
发布于:3个月前 (08-14) IP属地:四川省
使用Runtime Filter进行动态过滤减少join数据量,示例如下:
-- 启用 Runtime Filter
SET enable_runtime_filter = true;
-- 手动调整 Runtime Filter 类型
SET runtime_filter_type = "BLOOM_FILTER";
-- 查看执行计划中的 Runtime Filter
EXPLAIN
SELECT o.*
FROM orders o
JOIN (SELECT user_id FROM vip_users) v
ON o.user_id = v.user_id;这里特别说明下对应的filter使用类型:IN Filter:适用于高基数字段
Bloom Filter:适用于超高基数字段
MinMax Filter:适用于数值类型发布于:3个月前 (08-14) IP属地:四川省
使用colocation join进行共址join,保证关联数据在同一节点,适用于频繁join的维度表,示例如下:
-- 创建同组(Group)的表
CREATE TABLE table_a (
k1 INT,
...
) DISTRIBUTED BY HASH(k1) BUCKETS 32
PROPERTIES (
"colocation_with" = "group1"
);
CREATE TABLE table_b (
k1 INT,
...
) DISTRIBUTED BY HASH(k1) BUCKETS 32
PROPERTIES (
"colocation_with" = "group1"
);
-- 查询自动使用 Colocation Join
EXPLAIN
SELECT a.*, b.*
FROM table_a a
JOIN table_b b ON a.k1 = b.k1;发布于:3个月前 (08-14) IP属地:四川省
使用bucket shuffle join进行查询,通过数据分布预定位减少网络传输,适用于大表join大表的场景,示例如下:
-- 创建表时指定分布键
CREATE TABLE orders (
order_id BIGINT,
user_id BIGINT,
...
) DISTRIBUTED BY HASH(user_id) BUCKETS 32;
CREATE TABLE users (
user_id BIGINT,
...
) DISTRIBUTED BY HASH(user_id) BUCKETS 32;
-- 查询自动使用 Bucket Shuffle Join
EXPLAIN
SELECT o.*, u.name
FROM orders o
JOIN users u ON o.user_id = u.user_id;发布于:3个月前 (08-14) IP属地:四川省
在查询时,开启sql cache基于查询文本和参数进行精确匹配,示例如下:
-- 启用 SQL Cache
SET enable_sql_cache = true;
-- 查看缓存命中率
SHOW VARIABLES LIKE '%sql_cache%';在查询时常用的一些缓存优化相关的实践场景如下:-- 1. 使用参数化查询提高缓存命中率
-- 低效方式(每次参数不同都生成新缓存项)
SELECT*FROM orders WHERE user_id =1001;
SELECT*FROM orders WHERE user_id =1002;
-- 高效方式(使用视图或CTE)
CREATEVIEW user_orders AS
SELECT*FROM orders WHERE user_id = ${user_id};
-- 2. 控制缓存粒度
-- 小结果集查询适合缓存
SELECTCOUNT(*) FROM orders WHEREdate='2023-10-01';
-- 大结果集查询禁用缓存
SET enable_sql_cache =false;
SELECT*FROM large_table;发布于:3个月前 (08-14) IP属地:四川省
可以在查询的时候开启pipelinex引擎,他是在pipeline基础上增加了本地shuffle优化,示例如下:
-- 启用 PipelineX
set enable_pipeline_x_engine = true;
-- 查看执行计划中的 LocalExchange 算子
EXPLAIN SELECT COUNT(*) FROM large_table GROUP BY region;发布于:3个月前 (08-14) IP属地:四川省
可以在查询的时候开启pipeline引擎通过向量化直销和批处理技术进行优化,示例如下:
-- 启用 Pipeline 引擎
set enable_pipeline_engine = true;
-- 查看执行计划是否使用 Pipeline
EXPLAIN SELECT ... FROM ...;发布于:3个月前 (08-14) IP属地:四川省
我来回答
您需要 登录 后回答此问题!
