当前位置: 首页 > news >正文

OceanBase 分区裁剪(Partition Pruning)原理解读

分区裁剪(Partition Pruning)原理与应用详解

参考OceanBase v3.2.3 官方文档:分区裁剪

什么是分区裁剪?

分区裁剪(Partition Pruning)是数据库中对分区表进行查询优化的一种重要手段。通过该功能,数据库优化器可以避免访问与查询无关的分区,从而大幅提升 SQL 查询的执行效率。

当用户访问分区表时,往往只需要访问其中部分分区。优化器根据 SQL 中给定的条件与表的分区信息,自动过滤掉不需要访问的分区,这一过程就称为分区裁剪。


为什么需要分区裁剪?

分区表通常将数据按一定规则划分为多个分区存储。在执行查询时,如果无法提前确定所需分区,就可能需要扫描所有分区,导致查询效率低下。而通过分区裁剪,查询仅需访问特定分区,显著减少 I/O 操作和计算资源消耗,提升查询性能。


分区裁剪示例

我们通过一个简单的示例来说明分区裁剪的作用:

CREATE TABLE tbl1 (col1 INT,col2 INT
) PARTITION BY HASH(col1) PARTITIONS 5;SELECT * FROM tbl1 WHERE col1 = 1;

在这个例子中,col1 = 1 的数据全部位于第 1 号分区(p1),因此只需要访问该分区,而无需访问其他分区。

通过 EXPLAIN 查看执行计划,可以确认分区裁剪的效果:

EXPLAIN SELECT * FROM tbl1 WHERE col1 = 1 \G

输出结果如下:

*************************** 1. row ***************************
Query Plan: ===================================
|ID|OPERATOR  |NAME|EST. ROWS|COST|
-----------------------------------
|0 |TABLE SCAN|TBL1|990      |383 |
===================================Outputs & filters:
-------------------------------------0 - output([TBL1.COL1], [TBL1.COL2]), filter(nil),access([TBL1.COL1], [TBL1.COL2]), partitions(p1)

从执行计划中可以看到,仅分区 p1 被访问,说明分区裁剪已生效。


一级分区裁剪原理

Hash/List 分区

分区裁剪根据 WHERE 子句中的条件计算分区列的值,进而判断需要访问哪些分区。如果分区条件是一个表达式,且该表达式以整体形式出现在等值条件中,也可以进行分区裁剪。

例如:

CREATE TABLE t1 (c1 INT, c2 INT
) PARTITION BY HASH(c1 + c2) PARTITIONS 5;EXPLAIN SELECT * FROM t1 WHERE c1 + c2 = 1 \G
*************************** 1. row ***************************
Query Plan: ===================================
|ID|OPERATOR  |NAME|EST. ROWS|COST|
-----------------------------------
|0 |TABLE SCAN|t1  |5        |1303|
===================================Outputs & filters:
-------------------------------------0 - output([t1.c1], [t1.c2]), filter([t1.c1 + t1.c2 = 1]),access([t1.c1], [t1.c2]), partitions(p1)

执行计划输出中可以看到仅访问了分区 p1

Range 分区

Range 分区的裁剪是通过 WHERE 子句中分区键的范围与表定义的分区范围求交集,从而确定需要访问的分区。

需要注意的是,如果分区条件是一个函数,且查询条件是一个范围,则可能无法进行分区裁剪。例如:

CREATE TABLE t1 (c1 INT,c2 INT
) PARTITION BY RANGE(c1 + 1) (PARTITION p0 VALUES LESS THAN(100),PARTITION p1 VALUES LESS THAN(200)
);EXPLAIN SELECT * FROM t1 WHERE c1 < 150 AND c1 > 110 \G
*************************** 1. row ***************************
Query Plan: ============================================
|ID|OPERATOR           |NAME|EST. ROWS|COST|
--------------------------------------------
|0 |EXCHANGE IN DISTR  |    |19       |1410|
|1 | EXCHANGE OUT DISTR|    |19       |1303|
|2 |  TABLE SCAN       |t1  |19       |1303|
============================================Outputs & filters:
-------------------------------------0 - output([t1.c1], [t1.c2]), filter(nil)1 - output([t1.c1], [t1.c2]), filter(nil)2 - output([t1.c1], [t1.c2]), filter([t1.c1 < 150], [t1.c1 > 110]),access([t1.c1], [t1.c2]), partitions(p[0-1])

此时无法进行分区裁剪,需访问所有分区(p0 和 p1)。

而在等值查询中,分区裁剪仍可生效:

EXPLAIN SELECT * FROM t1 WHERE c1 = 150 \G
*************************** 1. row ***************************
Query Plan: ===================================
|ID|OPERATOR  |NAME|EST. ROWS|COST|
-----------------------------------
|0 |TABLE SCAN|t1  |1        |1303|
===================================Outputs & filters:
-------------------------------------0 - output([t1.c1], [t1.c2]), filter([t1.c1 = 150]),access([t1.c1], [t1.c2]), partitions(p1)

此时仅需访问分区 p1


二级分区裁剪原理

对于二级分区,分区裁剪分为两步:

  1. 根据一级分区键确定一级分区;
  2. 根据二级分区键确定二级分区。

最终访问的物理分区是一级和二级分区裁剪结果的乘积。

例如:

CREATE TABLE tbl2_rr (col1 INT,col2 INT
) 
PARTITION BY RANGE(col1)
SUBPARTITION BY RANGE(col2)
SUBPARTITION TEMPLATE (SUBPARTITION sp0 VALUES LESS THAN(1000),SUBPARTITION sp1 VALUES LESS THAN(2000)
) (PARTITION p0 VALUES LESS THAN(100),PARTITION p1 VALUES LESS THAN(200)
);EXPLAIN SELECT * FROM tbl2_rr 
WHERE (col1 = 1 OR col1 = 2) AND (col2 > 101 AND col2 < 150) \G
*************************** 1. row ***************************
Query Plan: ======================================
|ID|OPERATOR  |NAME   |EST. ROWS|COST|
--------------------------------------
|0 |TABLE SCAN|TBL2_RR|99       |53  |
======================================Outputs & filters:
-------------------------------------0 - output([TBL2_RR.COL1], [TBL2_RR.COL2]), filter(nil),access([TBL2_RR.COL1], [TBL2_RR.COL2]), partitions(p0sp0)1 row in set

执行计划显示仅访问物理分区 p0sp0,说明一二级分区裁剪均生效。


总结

分区裁剪是分区表查询优化中的关键机制,通过减少不必要的分区访问,显著提升查询性能。在使用时应注意:

  • 尽量在查询条件中明确分区键的值或范围;
  • 对于表达式作为分区键的情况,确保条件为等值查询以利于裁剪;
  • 二级分区裁剪是逐级进行的,最终访问分区为两级分区裁剪结果的乘积。

合理设计分区键和查询条件,可以充分发挥分区裁剪的优势,优化数据库查询性能。


注意:本文示例基于 OceanBase 数据库语法,但分区裁剪的原理在不同数据库系统中基本一致,可供广大数据库开发者与运维人员参考。

http://www.dtcms.com/a/343041.html

相关文章:

  • python + unicorn + xgboost + pytorch 搭建机器学习训练平台遇到的问题
  • Spring Boot集成腾讯云人脸识别实现智能小区门禁系统
  • windows无法访问某个服务器共享文件夹
  • linux中ctype.h字符判断函数实现原理
  • linux中的iptables的简介与常用基础用法
  • springboot人事管理系统源码和论文
  • Python编程练习100例(含答案)
  • HTTP 与 HTTPS:网络通信幽径上的安全秘钥
  • Promise详解:Promise解决ajax回调嵌套问题
  • system\core\init\init.cpp----LoadBootScripts()解析init.rc(2)
  • 五大主流ETL数据集成平台推荐
  • 鸿蒙 NEXT开发中轻松实现人脸识别功能
  • hadoop-3.3.6和hbase-2.4.13
  • 日志收集(ELK)
  • k8s--NetworkPolicy资源对象
  • 打工人项目日报计划
  • 搭建FTP文件共享服务器
  • linux 之 virtio 子系统核心的数据结构
  • DeepSeek R2难产:近期DeepSeek-V3.1 发布更新并开源,成功实现迈向 Agent 时代的第一步
  • 信息收集4----(收集网站指纹信息)
  • CSS 3D动画,围绕旋转动画Demo
  • 常见 Linux 网络命令梳理
  • AGV 技术落地场景解析:从制造业到仓储物流,看自动导引车的行业应用
  • 【Ruoyi解密-02.登录流程:】登录-找密码不抓瞎
  • 封装FTPSClient连接ftps服务器
  • 一个成熟的运维及售后岗位应掌握的知识体系详解
  • Linux动态库制作和使用
  • Manus AI 与多语言手写识别:技术、应用与未来
  • Nginx + Vue/React 前端 + API:防止路径混淆漏洞与跨域问题实战分享
  • [Mysql数据库] Mysql安全知识