如何用SQL语句来查询表或索引的行存/列存存储方式|OceanBase 用户问题集锦

一、问题背景

自OceanBase 4.3.0版本起,支持了列存引擎,允许表和索引以行存、纯列存或行列冗余的形式创建,且这些存储方式可以自由组合。除了使用 show create table命令来查看表和索引的存储类型外,也有用户询问如何通过SQL语句来查询表或索引的存储方式。那么,具体该如何操作呢?

1735278087

二、测试表

说明:这里仅列举了部分组合,还有其他的组合应该也是类似的,不再赘述,欢迎测试,拍砖。

-- 行存表,行存索引
create table  t1(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t1_c2(c2)) partition by hash(c1) partitions 3;
create table  t2(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t2_c2(c2)) partition by hash(c1) partitions 3 with column group(all columns);
create table  t3(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t3_c2(c2) with column group(all columns)) partition by hash(c1) partitions 3 with column group(all columns);-- 行存表,纯列存索引
create table  t4(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t4_c2(c2) with column group(each column)) partition by hash(c1) partitions 3;-- 行存表,行列混合索引
create table  t5(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t5_c2(c2) with column group(each column,all columns)) partition by hash(c1) partitions 3;-- 纯列存表,行存索引
create table  t6(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t6_c2(c2) with column group(all columns)) partition by hash(c1) partitions 3 with column group(each column);
create table  t7(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t7_c2(c2)) partition by hash(c1) partitions 3 with column group(each column);-- 行列混合表,行列混合索引
create table  t8(c1 int,c2 int,c3 int,c4 int,c5 int,primary key(c1),key idx_t8_c2(c2) with column group(each column,all columns)) partition by hash(c1) partitions 3 with column group(each column,all columns);

三、摸索

从列存相关的语法上可以看出,引入列存后新增加了 with column group (xxx) 的关键字,可以尝试搜一下哪些表的列上涉及了 column_group 相关的字段,从下面的结果看目前并没有标准表或者视图提供这样的信息。

MySQL [oceanbase]> select distinct table_name from __all_virtual_table 
where table_id in (select distinct table_id from __all_virtual_column where column_name like '%column_group%');
+--------------------------------------------+
| table_name                                 |
+--------------------------------------------+
| __all_table_history                        |
| __all_column_group                         |
| __all_column_group_history                 |
| __all_column_group_mapping                 |
| __all_column_group_mapping_history         |
| __all_virtual_core_all_table               |
| __all_virtual_table                        |
| __all_virtual_table_history                |
| __all_virtual_column_group                 |
| __all_virtual_column_group_mapping         |
| __all_virtual_column_group_history         |
| __all_virtual_column_group_mapping_history |
+--------------------------------------------+
12 rows in set (0.97 sec)

从 __all_virtual_column_group 表的 column_group_type 字段,凭感觉可以标识。

MySQL [oceanbase]> desc __all_virtual_column_group;
+-------------------+--------------+------+-----+---------+-------+
| Field             | Type         | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| tenant_id         | bigint(20)   | NO   | PRI | NULL    |       |
| table_id          | bigint(20)   | NO   | PRI | NULL    |       |
| column_group_id   | bigint(20)   | NO   | PRI | NULL    |       |
| gmt_create        | timestamp(6) | NO   |     | NULL    |       |
| gmt_modified      | timestamp(6) | NO   |     | NULL    |       |
| column_group_name | varchar(389) | NO   |     |         |       |
| column_group_type | bigint(20)   | NO   |     | NULL    |       |
| block_size        | bigint(20)   | NO   |     | NULL    |       |
| compressor_type   | bigint(20)   | NO   |     | NULL    |       |
| row_store_type    | bigint(20)   | NO   |     | NULL    |       |
+-------------------+--------------+------+-----+---------+-------+
10 rows in set (0.02 sec)

从代码 src/share/schema/ob_schema_struct.h 找到 column_group 类型的枚举值。

enum ObColumnGroupType : uint8_t
{DEFAULT_COLUMN_GROUP = 0,ALL_COLUMN_GROUP,ROWKEY_COLUMN_GROUP,SINGLE_COLUMN_GROUP,NORMAL_COLUMN_GROUP,MAX_COLUMN_GROUP
};

四、结论

经过测试发现如何标识 表或者索引是行存/纯列存/行列冗余的方式存储,这里之所以给 "结论"使用引号扩起来,原因:

1、受限于自己测试的 case 可能不完善,存在错误的情况,欢迎一起测试,交流。

2、随着版本的迭代,针对枚举值可能会有调整/比如增删等,应以实际版本中的枚举值为准。

  • 某个租户下当同一个 table_id 的 column_group_type 包含3 但是不包含1,输出:纯列存表
  • 某个租户下当同一个 table_id 的 column_group_type 包含1 和 3,输出:行列混合表
  • 其他情况均输出 :纯行存表

五、查询sql和结果

说明:可以按需调整 tenant_name/database_name

sql_1(混合查询)

select t1.tenant_name,t2.database_name,case when t2.table_type = 'user table' then t2.table_namewhen t2.table_type = 'index' then t2.index_nameend as table_name,t2.table_id,t2.data_table_id,t2.table_type,casewhen t2.table_type = 'user table' thencasewhen sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0 then '纯列存表'when sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) > 0 then '行列混合表'else '纯行存表'endwhen t2.table_type = 'index' thencasewhen sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0 then '纯列存索引'when sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) > 0 then '行列混合索引'else '纯行存索引'endend as storage_type,coalesce(t3.table_name, null) as main_table_name
from __all_virtual_column_group cg
join dba_ob_tenants t1 on cg.tenant_id = t1.tenant_id
join cdb_ob_table_locations t2 on cg.tenant_id = t2.tenant_id and cg.table_id = t2.table_id
left join cdb_ob_table_locations t3 on t2.data_table_id = t3.table_id
where t1.tenant_name in ('test1','test7')and t2.database_name in ('row_column_db','db100','db600')and t2.table_type in ('user table', 'index')
group by t1.tenant_name, t2.database_name, t2.table_name, t2.table_id, t2.data_table_id, t2.table_type, main_table_name
order by t1.tenant_name,t2.database_name, t2.table_name;

sql1_查询结果
+-------------+---------------+------------+----------+---------------+------------+--------------------+-----------------+
| tenant_name | database_name | table_name | table_id | data_table_id | table_type | storage_type       | main_table_name |
+-------------+---------------+------------+----------+---------------+------------+--------------------+-----------------+
| test1       | row_column_db | t1         |   596454 |          NULL | USER TABLE | 纯行存表           | NULL            |
| test1       | row_column_db | t2         |   596462 |          NULL | USER TABLE | 纯行存表           | NULL            |
| test1       | row_column_db | t3         |   596470 |          NULL | USER TABLE | 纯行存表           | NULL            |
| test1       | row_column_db | t4         |   596478 |          NULL | USER TABLE | 纯行存表           | NULL            |
| test1       | row_column_db | idx_t1_c2  |   596455 |        596454 | INDEX      | 纯行存索引         | t1              |
| test1       | row_column_db | idx_t2_c2  |   596463 |        596462 | INDEX      | 纯行存索引         | t2              |
| test1       | row_column_db | idx_t3_c2  |   596471 |        596470 | INDEX      | 纯行存索引         | t3              |
| test1       | row_column_db | idx_t4_c2  |   596479 |        596478 | INDEX      | 纯列存索引         | t4              |
| test7       | db100         | t8         |   500070 |          NULL | USER TABLE | 行列混合表         | NULL            |
| test7       | db100         | idx_t8_c2  |   500071 |        500070 | INDEX      | 行列混合索引       | t8              |
| test7       | db600         | t5         |   500045 |          NULL | USER TABLE | 纯行存表           | NULL            |
| test7       | db600         | t6         |   500053 |          NULL | USER TABLE | 纯列存表           | NULL            |
| test7       | db600         | t7         |   500061 |          NULL | USER TABLE | 纯列存表           | NULL            |
| test7       | db600         | idx_t5_c2  |   500046 |        500045 | INDEX      | 行列混合索引       | t5              |
| test7       | db600         | idx_t6_c2  |   500054 |        500053 | INDEX      | 纯行存索引         | t6              |
| test7       | db600         | idx_t7_c2  |   500062 |        500061 | INDEX      | 纯行存索引         | t7              |
+-------------+---------------+------------+----------+---------------+------------+--------------------+-----------------+
16 rows in set (3.45 sec)

sql2_查询纯列存的表/索引

select t1.tenant_name,t2.database_name,case when t2.table_type = 'user table' then t2.table_namewhen t2.table_type = 'index' then t2.index_nameend as table_name,t2.table_id,t2.data_table_id,t2.table_type,casewhen t2.table_type = 'user table' thencasewhen sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0 then '纯列存表'when sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) > 0 then '行列混合表'else '纯行存表'endwhen t2.table_type = 'index' thencasewhen sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0 then '纯列存索引'when sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) > 0 then '行列混合索引'else '纯行存索引'endend as storage_type,coalesce(t3.table_name, null) as main_table_name
from __all_virtual_column_group cg
join dba_ob_tenants t1 on cg.tenant_id = t1.tenant_id
join cdb_ob_table_locations t2 on cg.tenant_id = t2.tenant_id and cg.table_id = t2.table_id
left join cdb_ob_table_locations t3 on t2.data_table_id = t3.table_id
where t1.tenant_name in ('test1','test7')and t2.database_name in ('row_column_db','db100','db600')and t2.table_type in ('user table', 'index')
group by t1.tenant_name, t2.database_name, t2.table_name, t2.table_id, t2.data_table_id, t2.table_type, main_table_name
having(t2.table_type = 'user table' and sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0)or(t2.table_type = 'index' and sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0)
order by t1.tenant_name, t2.database_name, t2.table_name;

sql2_查询结果
+-------------+---------------+------------+----------+---------------+------------+-----------------+-----------------+
| tenant_name | database_name | table_name | table_id | data_table_id | table_type | storage_type    | main_table_name |
+-------------+---------------+------------+----------+---------------+------------+-----------------+-----------------+
| test1       | row_column_db | idx_t4_c2  |   596479 |        596478 | INDEX      | 纯列存索引      | t4              |
| test7       | db600         | t6         |   500053 |          NULL | USER TABLE | 纯列存表        | NULL            |
| test7       | db600         | t7         |   500061 |          NULL | USER TABLE | 纯列存表        | NULL            |
+-------------+---------------+------------+----------+---------------+------------+-----------------+-----------------+
3 rows in set (3.48 sec)

sql3_查询行列冗余的表/索引

SELECT tenant_name,database_name,table_name,table_id,data_table_id,table_type,storage_type,main_table_name
FROM (select t1.tenant_name,t2.database_name,case when t2.table_type = 'user table' then t2.table_namewhen t2.table_type = 'index' then t2.index_nameend as table_name,t2.table_id,t2.data_table_id,t2.table_type,casewhen t2.table_type = 'user table' thencasewhen sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0 then '纯列存表'when sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) > 0 then '行列混合表'else '纯行存表'endwhen t2.table_type = 'index' thencasewhen sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) = 0 then '纯列存索引'when sum(case when cg.column_group_type = 3 then 1 else 0 end) > 0 and sum(case when cg.column_group_type = 1 then 1 else 0 end) > 0 then '行列混合索引'else '纯行存索引'endend as storage_type,coalesce(t3.table_name, null) as main_table_namefrom __all_virtual_column_group cgjoin dba_ob_tenants t1 on cg.tenant_id = t1.tenant_idjoin cdb_ob_table_locations t2 on cg.tenant_id = t2.tenant_id and cg.table_id = t2.table_idleft join cdb_ob_table_locations t3 on t2.data_table_id = t3.table_idwhere t1.tenant_name in ('test1','test7')and t2.database_name in ('row_column_db','db100','db600')and t2.table_type in ('user table', 'index')group by t1.tenant_name, t2.database_name, t2.table_name, t2.table_id, t2.data_table_id, t2.table_type, main_table_name
) subquery
WHERE storage_type IN ('行列混合表', '行列混合索引')
ORDER BY tenant_name, database_name, table_name;

sql3_查询结果
+-------------+---------------+------------+----------+---------------+------------+--------------------+-----------------+
| tenant_name | database_name | table_name | table_id | data_table_id | table_type | storage_type       | main_table_name |
+-------------+---------------+------------+----------+---------------+------------+--------------------+-----------------+
| test7       | db100         | idx_t8_c2  |   500071 |        500070 | INDEX      | 行列混合索引       | t8              |
| test7       | db100         | t8         |   500070 |          NULL | USER TABLE | 行列混合表         | NULL            |
| test7       | db600         | idx_t5_c2  |   500046 |        500045 | INDEX      | 行列混合索引       | t5              |
+-------------+---------------+------------+----------+---------------+------------+--------------------+-----------------+
3 rows in set (3.33 sec)

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

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

相关文章

程序员如何高效学习API

API(应用程序编程接口)是软件开发中的关键组件,它允许不同的软件应用程序相互通信、交换数据和功能。作为程序员,掌握API的学习和应用是提升开发效率和代码质量的重要途径。本文将详细介绍程序员如何高效学习API,包括基…

如何播放视频文件

文章目录 1. 概念介绍2. 使用方法2.1 实现步骤2.2 具体细节3. 示例代码4. 内容总结我们在上一章回中介绍了"如何获取文件类型"相关的内容,本章回中将介绍如何播放视频.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 播放视频是我们常用的功能,不过Flutter官方…

Type-C单口便携显示器-LDR6021

Type-C单口便携显示器是一种新兴的显示设备,它凭借其便携性、高性能和广泛的应用场景等优势,正在成为市场的新宠。以下是Type-C单口便携显示器的具体运用方式: 一、连接与传输 1. **设备连接**:Type-C单口便携显示器通过Type-C接…

124.【C语言】数据结构之快速排序的小区间优化和非递归的解决方法

目录 1.小区间优化 测试代码 运行结果 2.非递归的解决方法(重要!) 递归产生的问题 一般来说,递归改非递归有两种方法 算法分析 递归产生的二叉树 栈的示意图 先写代码框架 再填写细节部分 1.小区间优化 回顾121.【C语言】数据结构之快速排序(未优化的Hoare排序存在…

汽车免拆诊断 | 2007款保时捷Carrera S车行驶中发动机冷却液温度报警灯异常点亮

故障现象 一辆2007款保时捷Carrera S车,搭载3.8 L自然吸气发动机,累计行驶里程约为7.8万km。车主反映,车辆行驶一段距离后,组合仪表上的发动机冷却液温度报警灯异常点亮。为此,在其他维修厂已更换过节温器、发动机冷却…

CES 2025|美格智能高算力AI模组助力“通天晓”人形机器人震撼发布

当地时间1月7日,2025年国际消费电子展(CES 2025)在美国拉斯维加斯正式开幕。美格智能合作伙伴阿加犀联合高通在展会上面向全球重磅发布人形机器人原型机——通天晓(Ultra Magnus)。该人形机器人内置美格智能基于高通QC…

Taro+Vue实现图片裁剪组件

cropper-image-taro-vue3 组件库 介绍 cropper-image-taro-vue3 是一个基于 Vue 3 和 Taro 开发的裁剪工具组件,支持图片裁剪、裁剪框拖动、缩放和输出裁剪后的图片。该组件适用于 Vue 3 和 Taro 环境,可以在网页、小程序等平台中使用。 源码 https:…

Opencv查找、绘制轮廓、圆形矩形轮廓和近似轮廓

查找、绘制轮廓、圆形矩形轮廓和近似轮廓 目录 查找、绘制轮廓、圆形矩形轮廓和近似轮廓1 轮廓查找和绘制1.1 轮廓查找1.1.1 函数和参数1.1.2 返回值 1.2 轮廓绘制1.2.1 函数和参数 1.3 步骤1.4 实际测试绘制轮廓 2 绘制近似轮廓2.1 函数和参数2.2 查找特定轮廓2.3 近似轮廓测试…

【Linux】模拟Shell命令行解释器

一、知识补充 1.1 snprintf snprintf() 是 C语言的一个标准库函数&#xff0c;定义在<stdio.h>头文件中。 snprintf() 函数的功能是格式化字符串&#xff0c;并将结果存储在指定的字符数组中。该函数的原型如下&#xff1a; int snprintf(char *str, size_t size, con…

云计算基础,虚拟化原理

文章目录 一、虚拟化1.1 什么是虚拟化1.2 虚拟化类型 二 、存储虚拟化2.1 存储指标2.2 存储类型2.3 存储协议2.4 RAID 三、内存 i/O虚拟化3.1 内存虚拟化基本概念地址空间转换原理内存共享与隔离原理 3.2 I/O 虚拟化基本概念模拟&#xff08;Emulation&#xff09;方式半虚拟化…

Vue3 + Vite + Electron + Ts 项目快速创建

一、创建 Vue 项目 1. 创建项目 pnpm create vite 2. 安装依赖 cd excel-electron pnpm install 3. 运行项目 pnpm dev 二、添加 Electron 1. 安装 electron pnpm add electron -D 2. 修改 package.json 添加入口 js 和执行命令。 {"main": "dist-ele…

pytest+allure 入门

使用allure如何生成自动化测试报​​​​​​告 &#xff1f;一文详解allure的使用 。_allure测试报告-CSDN博客 例子&#xff1a; import allure import pytest import osallure.epic("闹钟") allure.feature("闹钟增删") class TestSchedule():def setu…

新活动平台建设历程与架构演进

01 前言 历时近两年的重新设计和迭代重构&#xff0c;用户技术中心的新活动平台建设bilibili活动中台终于落地完成&#xff01;并迎来了里程碑时刻 —— 接过新老迭代的历史交接棒&#xff0c;从内到外、从开发到搭建实现全面升级&#xff0c;开启了活动生产工业化新时代&#…

从CentOS到龙蜥:企业级Linux迁移实践记录(系统安装)

引言&#xff1a; 随着CentOS项目宣布停止维护CentOS 8并转向CentOS Stream&#xff0c;许多企业和组织面临着寻找可靠替代方案的挑战。在这个背景下&#xff0c;龙蜥操作系统&#xff08;OpenAnolis&#xff09;作为一个稳定、高性能且完全兼容的企业级Linux发行版&#xff0…

MR实战:IP地址去重

文章目录 1. 实战概述2. 提出任务2.1 原始问题2.2 简单化处理 3. 准备数据3.1 在云主机上创建文本文件3.2 上传文件到HDFS指定目录 4. 实现步骤4.1 创建Maven项目4.2 添加相关依赖4.3 创建日志属性文件4.4 创建网址去重映射器类4.5 创建网址去重归并器类4.6 创建网址去重驱动器…

AnaConda下载PyTorch慢的解决办法

使用Conda下载比较慢&#xff0c;改为pip下载 复制下载链接到迅雷下载 激活虚拟环境&#xff0c;安装whl&#xff0c;即可安装成功 pip install D:\openai.wiki\ChatGLM2-6B\torch-2.4.1cu121-cp38-cp38-win_amd64.whl

Photoshop PS批处理操作教程(批量修改图片尺寸、参数等)

前言 ‌Photoshop批处理的主要作用‌是通过自动化处理一系列相似的操作来同时应用于多张图片&#xff0c;从而节省时间和精力&#xff0c;提高工作效率。批处理功能特别适用于需要批量处理的任务&#xff0c;如图像尺寸调整、颜色校正、水印添加等‌。 操作步骤 1.创建动作 …

Web渗透测试之XSS跨站脚本 防御[WAF]绕过手法

目录 XSS防御绕过汇总 参考这篇文章绕过 XSS payload XSS防御绕过汇总 服务端知道有网络攻击或者xss攻 Html 通过js代码 标签属性等手段进行一个过滤 不允许出现css的payload 前端过滤 我可以在抓包工具里面修改 抓包工具是不受前端的防御 也 就是浏览器 服务端过滤…

git提交

基本流程&#xff1a;新建分支 → 分支上开发(写代码) → 提交 → 合并到主分支 拉取最新代码因为当前在 master 分支下&#xff0c;你必须拉取最新代码&#xff0c;保证当前代码与线上同步&#xff08;最新&#xff09;&#xff0c;执行以下命令&#xff1a;bashgit pull orig…

多云架构,JuiceFS 如何实现一致性与低延迟的数据分发

随着大模型的普及&#xff0c;GPU 算力成为稀缺资源&#xff0c;单一数据中心或云区域的 GPU 资源常常难以满足用户的全面需求。同时&#xff0c;跨地域团队的协作需求也推动了企业在不同云平台之间调度数据和计算任务。多云架构正逐渐成为一种趋势&#xff0c;然而该架构下的数…