Apache Doris:深度优化与最佳实践

引言

在前两篇文章中,我们已经介绍了 Apache Doris 的基本概念、安装配置、基础操作以及一些高级特性。本文将进一步深入探讨 Doris 的性能优化技巧、高级查询优化、数据建模最佳实践以及常见问题的解决方法。通过本文,读者将能够更好地理解和应用 Doris 的高级功能,从而提升系统的整体性能和稳定性。

性能优化技巧

1. 合理设置 Bucket 数

Bucket 数直接影响数据的分布和查询性能。合理的 Bucket 数可以避免数据倾斜,提高查询效率。

实践示例

假设我们有一个用户行为表 user_behavior,我们需要根据 user_id 进行分区和桶分配。

CREATE TABLE user_behavior (user_id INT,item_id INT,category_id INT,behavior STRING,ts TIMESTAMP
) ENGINE=OLAP
PARTITION BY RANGE (ts)
(PARTITION p1 VALUES LESS THAN ('2024-01-01'),PARTITION p2 VALUES LESS THAN ('2024-02-01'))
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES ("replication_num" = "1");

2. 预聚合

预聚合可以显著提高查询性能,特别是在需要频繁进行聚合操作的场景中。

实践示例

假设我们需要频繁统计每天各个类别的销售数量,可以创建一个预聚合表 pre_aggregated_sales

CREATE TABLE pre_aggregated_sales (category_id INT,ts DATE,sales_count BIGINT SUM
) ENGINE=OLAP AGGREGATE KEY(category_id, ts)
DISTRIBUTED BY HASH(category_id) BUCKETS 10
PROPERTIES ("replication_num" = "1");-- 插入预聚合数据
INSERT INTO pre_aggregated_sales
SELECT category_id, DATE(ts), COUNT(*) AS sales_count
FROM user_behavior
GROUP BY category_id, DATE(ts);

3. 索引优化

合理使用索引可以显著提高查询性能。Doris 支持多种索引类型,包括 Bitmap 索引和 Bloom Filter 索引。

Bitmap 索引

适用于基数较小的列,如性别、状态等。

CREATE TABLE bitmap_index_table (user_id INT,gender TINYINT BITMAP INDEX
) ENGINE=OLAP DUPLICATE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES ("replication_num" = "1");
Bloom Filter 索引

适用于需要快速过滤大量数据的场景。

CREATE TABLE bloom_filter_table (user_id INT,name VARCHAR(255) BLOOM FILTER (100000, 0.01)
) ENGINE=OLAP DUPLICATE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES ("replication_num" = "1");

4. 缓存机制

利用 Doris 的缓存机制可以减少磁盘 I/O,提高查询速度。

实践示例

开启查询缓存:

SET enable_query_cache = true;

5. 分区策略

合理的分区策略可以显著提高查询性能。Doris 支持范围分区和列表分区。

范围分区

适用于按时间范围划分数据的场景。

CREATE TABLE range_partition_table (user_id INT,order_id INT,order_date DATE
) ENGINE=OLAP DUPLICATE KEY(user_id, order_id)
PARTITION BY RANGE (order_date)
(PARTITION p1 VALUES LESS THAN ('2024-01-01'),PARTITION p2 VALUES LESS THAN ('2024-02-01'))
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES ("replication_num" = "1");
列表分区

适用于按特定值划分数据的场景。

CREATE TABLE list_partition_table (user_id INT,region STRING
) ENGINE=OLAP DUPLICATE KEY(user_id)
PARTITION BY LIST (region)
(PARTITION p1 VALUES IN ('North', 'South'),PARTITION p2 VALUES IN ('East', 'West'))
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES ("replication_num" = "1");

高级查询优化

1. 子查询优化

子查询在某些情况下会导致性能下降。通过改写查询语句,可以显著提高查询性能。

实践示例

假设我们需要查询每个用户的最近一次购买记录。

原始查询

SELECT user_id, MAX(ts) AS latest_purchase
FROM user_behavior
GROUP BY user_id;

优化后的查询

WITH latest_purchase AS (SELECT user_id, MAX(ts) AS latest_purchase_tsFROM user_behaviorGROUP BY user_id
)
SELECT ub.user_id, ub.item_id, ub.category_id, ub.ts
FROM user_behavior ub
JOIN latest_purchase lp ON ub.user_id = lp.user_id AND ub.ts = lp.latest_purchase_ts;

2. 索引覆盖

索引覆盖是指查询的所有列都在索引中,这样可以避免回表查询,提高查询性能。

实践示例

假设我们有一个用户表 users,经常需要查询用户的姓名和年龄。

CREATE TABLE users (user_id INT,name VARCHAR(255),age INT,email VARCHAR(255)
) ENGINE=OLAP DUPLICATE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES ("replication_num" = "1");-- 创建索引覆盖的二级索引
ALTER TABLE users ADD INDEX idx_name_age (name, age);

3. 并行查询

Doris 支持并行查询,通过增加并行度可以显著提高查询性能。

实践示例

增加并行度:

SET parallel_exec_instance_num = 10;

数据建模最佳实践

1. 数据模型选择

Doris 支持多种数据模型,每种模型适用于不同的场景。选择合适的数据模型对于提高查询性能至关重要。

Aggregate Key 模型

适用于需要对某个维度进行聚合计算的场景。

CREATE TABLE agg_table (k1 INT,v1 INT SUM,v2 DOUBLE MAX
) ENGINE=OLAP AGGREGATE KEY(k1)
DISTRIBUTED BY HASH(k1) BUCKETS 10
PROPERTIES ("replication_num" = "1");
Unique Key 模型

适用于需要唯一键值的场景。

CREATE TABLE unique_table (k1 INT,v1 VARCHAR(255)
) ENGINE=OLAP UNIQUE KEY(k1)
DISTRIBUTED BY HASH(k1) BUCKETS 10
PROPERTIES ("replication_num" = "1");
Duplicate Key 模型

适用于需要保留所有记录的场景。

CREATE TABLE dup_table (k1 INT,v1 VARCHAR(255)
) ENGINE=OLAP DUPLICATE KEY(k1)
DISTRIBUTED BY HASH(k1) BUCKETS 10
PROPERTIES ("replication_num" = "1");

2. 数据清洗与预处理

在数据导入 Doris 之前,进行必要的数据清洗和预处理可以提高数据质量和查询性能。

实践示例

假设我们有一个原始数据文件 raw_data.csv,需要进行数据清洗后再导入 Doris。

# 数据清洗脚本
awk -F ',' '{ if ($3 > 0 && $4 <= 100) print $0 }' raw_data.csv > cleaned_data.csv
LOAD LABEL test.load_label_1
(DATA INFILE("file:///path/to/cleaned_data.csv")INTO TABLE example_tableCOLUMNS TERMINATED BY ","(id, name, age, join_date)
);

3. 数据生命周期管理

合理管理数据的生命周期,定期删除不再需要的历史数据,可以节省存储空间并提高查询性能。

实践示例

假设我们需要定期删除一年前的数据。

DELETE FROM user_behavior
WHERE ts < DATE_SUB(CURDATE(), INTERVAL 1 YEAR);

常见问题及解决方案

1. 数据导入失败

问题描述:数据导入过程中遇到错误,提示“Load failed”。

解决方案

  • 检查数据格式是否符合表结构定义。
  • 查看 Doris 日志,定位具体的错误原因。
  • 使用 SHOW LOAD 命令查看导入任务的状态和错误信息。
SHOW LOAD WHERE Label = 'load_label_1';

2. 查询性能低下

问题描述:查询响应时间过长。

解决方案

  • 分析查询计划,找出性能瓶颈。
  • 优化索引和分区策略。
  • 调整 Doris 的配置参数,如 max_memory_limitnum_nodes_per_scan
EXPLAIN SELECT * FROM large_table WHERE k1 > 1000;

3. 集群扩容

问题描述:随着数据量的增长,现有集群无法满足需求。

解决方案

  • 添加新的 BE 节点。
  • 调整 Bucket 数和分区策略,重新平衡数据分布。
# 添加新节点
./bin/add_backend.sh <new_be_host>:<be_port>

4. 数据一致性问题

问题描述:数据更新后,查询结果不一致。

解决方案

  • 使用分布式事务确保数据的一致性。
  • 调整事务隔离级别,确保事务的正确性。
BEGIN;
INSERT INTO example_table VALUES (4, 'David', 30, '2023-04-01');
UPDATE example_table SET age = 31 WHERE id = 4;
COMMIT;

5. 内存不足

问题描述:系统运行过程中出现内存不足的问题。

解决方案

  • 增加节点的内存配置。
  • 优化查询语句,减少内存占用。
  • 调整 Doris 的内存相关配置参数,如 max_memory_limit
# 修改配置文件 be.conf
max_memory_limit = 32GB

结论

本文深入探讨了 Apache Doris 的性能优化技巧、高级查询优化、数据建模最佳实践以及常见问题的解决方案。通过本文,读者将能够更好地理解和应用 Doris 的高级功能,从而提升系统的整体性能和稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/886514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB 使用教程 —— 命令窗口输入命令,工作区显示变量

命令在命令窗口输入变量在工作区显示 MATLAB 桌面包含的面板如下&#xff1a; 当前文件夹 - 此面板允许访问项目文件夹和文件。命令窗口 - 这是主要区域&#xff0c;用户在命令行中输入命令&#xff0c;命令提示符(>>).工作区 - 工作区显示所有变量&#xff0c;无论是创…

nodejs入门(1):nodejs的前后端分离

一、引言 我关注nodejs还是从前几年做了的一个电力大数据展示系统开始的&#xff0c;当然&#xff0c;我肯定是很多年的计算机基础的&#xff0c;万变不离其宗。 现在web网站都流行所谓的前后端结构&#xff0c;不知不觉我也开始受到这个影响&#xff0c;以前都是前端直接操作…

前端开发之打印功的使用和实例(vue-print-nb)

通过插件来进行实现 前言效果图1、安装插件vue2vue32、 引入Vue项目2、 使用2.1、在项目中创建按钮并且使用v-print绑定绑定打印事件2.2、编写要打印的内容,给内容附加唯一的id2.3、绑定的时间的方法和参数3、整体代码(此代码是通过vue3来进行实现的但是逻辑都是一样的)前言…

一文简单了解Android中的input流程

在 Android 中&#xff0c;输入事件&#xff08;例如触摸、按键&#xff09;从硬件传递到应用程序并最终由应用层消费。整个过程涉及多个系统层次&#xff0c;包括硬件层、Linux 内核、Native 层、Framework 层和应用层。我们将深入解析这一流程&#xff0c;并结合代码逐步了解…

opencv kdtree pcl kdtree 效率对比

由于项目中以一个环节需要使用kdtree ,对性能要求比较严苛&#xff0c;所以看看那个kdtree效率高一些。对比了opencv和pcl。 #include <array> #include <deque> #include <fstream> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp…

学习日志011--模块,迭代器与生成器,正则表达式

一、python模块 在之前学习c语言时&#xff0c;我们学了分文件编辑&#xff0c;那么在python中是否存在类似的编写方式&#xff1f;答案是肯定的。python中同样可以实现分文件编辑。甚至还有更多的好处&#xff1a; ‌提高代码的可维护性‌&#xff1a;当代码被分成多个文件时…

idea 弹窗 delete remote branch origin/develop-deploy

想删除远程分支&#xff0c;就选delete&#xff0c;仅想删除本地分支&#xff0c;选cancel&#xff1b; 在 IntelliJ IDEA 中遇到弹窗提示删除远程分支 origin/develop-deploy&#xff0c;这通常是在 Git 操作过程中出现的情况&#xff0c;可能是在执行如 git branch -d 或其他…

湘潭大学软件工程算法设计与分析考试复习笔记(一)

文章目录 前言随机类&#xff08;第七章&#xff09;随机概述数值随机化舍伍德拉斯维加斯蒙特卡罗 模拟退火遗传人工神经网络 回溯&#xff08;第五章&#xff09;动态规划&#xff08;第四章&#xff09;后记 前言 考试还剩十一天&#xff0c;现在准备开始复习这门课了。好像全…

Linux性能优化之火焰图的起源

Linux火焰图的起源与性能优化专家 Brendan Gregg 密切相关&#xff0c;他在 2011 年首次提出这一工具&#xff0c;用于解决性能分析过程中可视化和数据解读的难题。 1. 背景&#xff1a;性能优化的需求 在现代计算中&#xff0c;性能优化往往需要对程序执行中的热点和瓶颈进行…

【论文精读】GOT-OCR2.0源码论文——打破传统OCR流程的多模态视觉-语言大模型架构:预训练VitDet 视觉模型+ 阿里通义千问Qwen语言模型

作为本系列的开篇文章&#xff0c;首先定下本系列的整体基调。论文精读系列&#xff0c;旨在记录研读深度学习、强化学习相关论文的个人心得和理解&#xff0c;仅供参考&#xff0c;欢迎指正错误和研究探讨。 所有文章只会摘选论文部分进行分析&#xff0c;且不一定按原文行文顺…

使用 Qt 实现基于海康相机的图像采集和显示系统(不使用外部视觉库,如Halcon\OpenCv)[工程源码联系博主索要]

本文将梳理一个不借助外部视觉库&#xff08;如 OpenCV/Halcon&#xff09;的海康相机图像采集和显示 Demo。该程序直接使用 Qt GUI 来显示图像。通过海康 MVS SDK 实现相机的连接、参数设置、图像采集和异常处理等功能&#xff0c;并通过 Qt 界面展示操作结果。 1. 功能概述 …

在Ubuntu22.04上源码构建ROS noetic环境

Ubuntu22.04上源码构建ROS noetic 起因准备环境创建工作目录并下载源码安装编译依赖包安装ros_comm和rosconsole包的两个补丁并修改pluginlib包的CMakeLists的编译器版本编译安装ROS noetic和ros_test验证 起因 最近在研究VINS-Mono从ROS移植到ROS2&#xff0c;发现在编写feat…

C++——类和对象(part2)

前言 本篇博客继续为大家介绍类与对象的知识&#xff0c;承接part1的内容&#xff0c;本篇内容是类与对象的核心内容&#xff0c;稍微有些复杂&#xff0c;如果你对其感兴趣&#xff0c;请继续阅读&#xff0c;下面进入正文部分。 1. 类的默认成员函数 默认成员函数就是用户…

matlab实现主成分分析方法图像压缩和传输重建

原创 风一样的航哥 航哥小站 2024年11月12日 15:23 江苏 为了研究图像的渐进式传输技术&#xff0c;前文提到过小波变换&#xff0c;但是发现小波变换非常适合传输缩略图&#xff0c;实现渐进式传输每次传输的数据量不一样&#xff0c;这是因为每次变换之后低频成分大约是上一…

【HarmonyOS】鸿蒙系统在租房项目中的项目实战(二)

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…

Scala-字符串(拼接、printf格式化输出等)-用法详解

Scala 一、 使用 号连接字符串 在 Scala 中&#xff0c; 运算符实际上会调用 String 类的 concat 方法或者使用字符串的加法操作&#xff0c;生成一个新的字符串。 字符串是不可变的&#xff0c;每次拼接都会创建一个新的字符串。 Mr. yuTips&#xff1a; 性能相对较差&…

ISCTF2024

ezlogin 源码审计 先审源码,纯js题 const express require(express); const app express(); const bodyParser require(body-parser); var cookieParser require(cookie-parser); var serialize require(node-serialize); app.use(bodyParser.urlencoded({ e…

使用真实 Elasticsearch 进行更快的集成测试

作者&#xff1a;来自 Elastic Piotr Przybyl 了解如何使用各种数据初始化和性能改进技术加快 Elasticsearch 的自动化集成测试速度。 在本系列的第 1 部分中&#xff0c;我们探讨了如何编写集成测试&#xff0c;让我们能够在真实的 Elasticsearch 环境中测试软件&#xff0c;并…

MySQL:联合查询(2)

首先写一个三个表的联合查询 查询所有同学的每门课成绩&#xff0c;及同学的个人信息 1.我们首先要确定使用哪些表 学生表&#xff0c;课程表&#xff0c;成绩表 2.取笛卡尔积 select * from score,student,course; 3. 确定表与表之间的联合条件 select * from score,stud…

Vue3学习笔记(下)

文章目录 Vue3学习笔记&#xff08;下&#xff09;组合式API下的父子通信父传子子传父 模板引用defineExpose()provide和injectvue3新特性 - defineOptionsvue3新特性 - defineModelPiniaPinia异步写法 Vue3学习笔记&#xff08;下&#xff09; 组合式API下的父子通信 父传子…