openGauss 高级特性:优化器、存储引擎与分区管理

openGauss 作为一款企业级开源数据库,其强大的内核能力主要体现在智能优化器、多模存储引擎以及海量数据分区管理上。深入掌握这些高级特性及完整语法,是进行数据库架构设计与性能调优的基石。

思维导图



一、智能查询优化器

优化器 是数据库的大脑,负责将 SQL 语句转换为最高效的执行计划。

1. 核心机制对比

RBO :基于固定规则。例如有索引就用索引。它不考虑表中有多少数据,逻辑简单但僵化,适用于简单查询或元数据查询。
CBO :基于代价估算。它是 openGauss 的主力优化器。它通过计算 CPU、内存、I/O 等资源的消耗,选择代价最小的路径。CBO 严重依赖统计信息的准确性。

2. 统计信息管理

为了让 CBO 聪明地工作,必须定期收集统计信息。

sql 复制代码
-- 1. 收集全库统计信息 (通常由自动维护任务执行)
ANALYZE;

-- 2. 收集指定表的统计信息 (标准用法)
ANALYZE customer;

-- 3. 收集指定表特定列的统计信息
ANALYZE customer (age, city);

-- 4. 打印详细进度信息 (用于诊断)
ANALYZE VERBOSE customer;

二、多模表存储引擎

openGauss 支持在一个数据库中混合使用多种存储模式,以适配不同的业务负载。

1. 行存表:OLTP 首选

数据按行连续存储,适合点查询和高频事务

完整创建语法

sql 复制代码
CREATE TABLE table_name (
    column_name data_type,
    ...
)
WITH (
    ORIENTATION = ROW,        -- 显式指定为行存
    COMPRESSION = NO,         -- 行存通常不压缩或轻量压缩
    FILLFACTOR = 80           -- 预留空间参数,优化 UPDATE 性能
)
TABLESPACE tablespace_name;   -- 指定存储表空间

2. 列存表:OLAP 利器

数据按列连续存储,适合统计分析和海量数据

完整创建语法

sql 复制代码
CREATE TABLE table_name (
    column_name data_type,
    ...
)
WITH (
    ORIENTATION = COLUMN,     -- 显式指定为列存
    COMPRESSION = HIGH,       -- 设置压缩级别 (LOW/MIDDLE/HIGH)
    MAX_BATCHROW = 60000,     -- 单个 CU (压缩单元) 的最大行数
    PARTIAL_CLUSTER_ROWS = 600000 -- 局部聚簇行数,优化顺序扫描
);

3. 内存表:极致低延迟

MOT数据全内存驻留,无锁并发。

完整创建语法

MOT 表通过外表 机制实现。

sql 复制代码
-- 1. 创建 MOT 专用表 (通常只需指定 FOREIGN 表,部分版本支持直接 CREATE FOREIGN TABLE)
CREATE FOREIGN TABLE mot_table (
    id INT NOT NULL,
    data CHAR(20)
)
SERVER mot_server;  -- 指定使用内置的 MOT 服务引擎

三、分区表:海量数据治理

分区表将大表物理拆分为小文件,大幅提升查询和维护效率。

1. 范围分区

最常用的策略,按数值范围或时间周期划分。
完整语法示例

sql 复制代码
CREATE TABLE sales_range (
    sale_id INT,
    sale_date DATE,
    amount DECIMAL
)
PARTITION BY RANGE (sale_date) (
    -- 定义明确的范围分区
    PARTITION p_q1_2023 VALUES LESS THAN ('2023-04-01'),
    PARTITION p_q2_2023 VALUES LESS THAN ('2023-07-01'),
    -- 定义表空间,实现冷热分离
    PARTITION p_q3_2023 VALUES LESS THAN ('2023-10-01') TABLESPACE ts_ssd,
    -- 兜底分区,存放超出上述范围的数据
    PARTITION p_max VALUES LESS THAN (MAXVALUE) TABLESPACE ts_hdd    );

2. 列表分区

按离散枚举值划分,适合地域、类别等字段。

完整语法示例

sql 复制代码
CREATE TABLE users_list (
    user_id INT,
    region VARCHAR(20)
)
PARTITION BY LIST (region) (
    -- 单个值分区
    PARTITION p_beijing VALUES ('Beijing'),
    PARTITION p_shanghai VALUES ('Shanghai'),
    -- 多个值合并分区
    PARTITION p_south VALUES ('Guangzhou', 'Shenzhen'),
    -- 默认分区 (可选)
    PARTITION p_other VALUES (DEFAULT)
);

3. 哈希分区

按哈希值打散,用于数据均匀分布,避免热点。

完整语法示例

sql 复制代码
CREATE TABLE orders_hash (
    order_id UUID,
    customer_id INT
)
PARTITION BY HASH (customer_id) (
    -- 只需指定分区数量,系统自动计算哈希边界
    PARTITION p0,
    PARTITION p1,
    PARTITION p2,
    PARTITION p3
);

四、练习

1.openGauss 默认使用的优化器是哪一种?它主要依据什么来生成执行计划?

  1. 当一张表的数据发生大量变更(如插入了 50% 的新数据)后,为了防止 SQL 执行变慢,管理员应该立即执行什么命令?

  2. 编写 SQL 语句,创建一个名为 t_row_basic 的行存表,包含 id (INT) 和 info (TEXT) 两列,并显式指定其存储方向参数。

  3. 编写 SQL 语句,创建一个名为 t_col_analytics 的列存表,包含 s_date (DATE) 和 pv (BIGINT) 两列,并将其压缩级别设置为 HIGH

  4. 某业务系统需要每天进行大量的单行 INSERT 操作,且主要是按主键 ID 进行单点查询,应选择行存还是列存?

  5. 某数据仓库需要存储海量历史日志,且查询模式通常是扫描几百万行数据但只读取其中的两三列进行 SUM 计算,对应选择行存还是列存?

  6. MOT 表的数据和索引主要存储在哪里?这为它带来了什么显著的性能优势?

  7. 如果要按"省份"(如 'Beijing', 'Shanghai')这类离散值对用户表进行分区,应该使用哪种分区策略?

  8. 编写 SQL 语句,创建一个名为 t_log_range 的范围分区表。按 log_id (INT) 列分区:p_small 存储小于 1000 的数据,p_medium 存储小于 2000 的数据,p_max 存储剩余所有数据。

  9. 在存储同样的数据量时,通常哪种存储模式占用的磁盘空间更少?

  10. 简述列存表在执行 SELECT count(col_A) FROM table 这类只涉及单列的聚合查询时,比行存表快的主要原因。

  11. 简述 RBO (基于规则的优化器) 相比于 CBO 的主要缺点是什么?

  12. CREATE TABLEWITH 子句中,用于指定表存储方向(行或列)的参数名称是什么?

  13. 使用分区表时,数据库可以通过分析查询条件(WHERE)直接跳过不符合条件的分区文件,这一特性被称为什么?

  14. 对于列存表,频繁的 UPDATEDELETE 操作会导致磁盘空间膨胀且无法自动回收,通常需要手动执行什么命令来彻底重组表并回收空间?


五、解析

1. CBO,主要依据统计信息计算出的代价。

解析: RBO 依据固定规则,CBO 依据数据统计信息,openGauss 核心是 CBO。

2.

sql 复制代码
ANALYZE table_name;

解析 : 数据大量变更会导致旧的统计信息失真,误导优化器生成错误的执行计划。ANALYZE 命令用于重新收集统计信息。

3.

sql 复制代码
CREATE TABLE t_row_basic (id INT, info TEXT) WITH (ORIENTATION = ROW);

解析 : 行存表的关键参数是 ORIENTATION = ROW

4.

sql 复制代码
CREATE TABLE t_col_analytics (s_date DATE, pv BIGINT) WITH (ORIENTATION = COLUMN, COMPRESSION = HIGH);

解析 : 列存表使用 ORIENTATION = COLUMN,并通过 COMPRESSION 参数控制压缩等级。

5. 行存表

解析: OLTP 场景(高频插入、事务处理、点查询)是行存表的绝对强项。

6. 列存表

解析: OLAP 场景(聚合分析、海量扫描、只读取特定列)是列存表的设计初衷,能大幅减少 I/O。

7. 存储在内存中。优势:实现了极低的事务延迟和极高的吞吐量,消除了磁盘 I/O 瓶颈。

解析: MOT 全称 Memory-Optimized Table,是全内存引擎,非缓存机制。

8. 列表分区

解析: 省份是有限的、离散的枚举值,适合 List 分区;连续的数值或时间适合 Range 分区。

9.

sql 复制代码
CREATE TABLE t_log_range (log_id INT) PARTITION BY RANGE (log_id) (
    PARTITION p_small VALUES LESS THAN (1000),
    PARTITION p_medium VALUES LESS THAN (2000),
    PARTITION p_max VALUES LESS THAN (MAXVALUE)
);

解析 : Range 分区需要定义上界,MAXVALUE 用于捕获所有超出前面定义范围的数据。

10. 列存表

解析: 列存表中同一列的数据类型相同,重复度高,利用 RLE (运行长度编码) 等算法能获得极高的压缩比(通常 10 倍以上)。

11. I/O 裁剪或只读取需要的列。列存表只需要物理读取 col_A 这一列的数据块,而行存表必须将包含所有列的整行数据读入内存,产生了大量无效 I/O。

解析: 读取的数据量越少,查询速度越快。

12. RBO 忽略数据的实际分布情况,仅依靠硬编码规则,在数据分布不均时如数据倾斜容易生成次优的执行计划。

解析: 例如索引列全是同一个值,RBO 仍可能强制走索引,导致随机 I/O 激增,性能不如全表扫描。

13. ORIENTATION

解析 : 语法为 WITH (ORIENTATION = ROW | COLUMN)

14. 分区剪枝

解析: 这是分区表性能提升的核心原理,系统只扫描包含目标数据的分区,跳过无关分区。

15. VACUUM FULL table_name;

解析 : 列存表的删除通常是逻辑标记删除,物理空间不会立即释放。VACUUM FULL 会重写整个表文件,彻底回收空间。

日期:2025年12月25日

专栏:openGauss

相关推荐
DemonAvenger2 小时前
Redis主从复制原理与实战:构建高可用缓存架构
数据库·redis·性能优化
X.Ming 同学2 小时前
QXlsx 库在麒麟 Linux(Qt 5.15.2)下完整安装步骤(含问题排查 & 经验总结)
linux·数据库·qt
卜锦元2 小时前
Golang后端性能优化手册(第一章:数据库性能优化)
大数据·开发语言·数据库·人工智能·后端·性能优化·golang
杨二K2 小时前
Milvus性能权衡
数据库·人工智能·milvus
一往无前fgs2 小时前
【问题记录】在openEuler 24 系统使用宝塔面板安装Mysql数据库启动失败问题
数据库·mysql
航Hang*2 小时前
第3章:复习篇——第5-2节:数据库编程2
数据库·笔记·sql·mysql·sqlserver
islandzzzz2 小时前
SQL学习应用工作场景(2)--执行优先级+语法顺序+保留2位小数
数据库·sql·学习
开开心心_Every2 小时前
定时管理进程:防止沉迷电脑的软件推荐
xml·java·运维·服务器·网络·数据库·excel
hopsky2 小时前
SQL语义校验方案
数据库·oracle