列顺序占用存储大小的影响 in Oracle、MySQL、PostGreSQL

列顺序占用存储大小的影响 in Oracle、MySQL、PostGreSQL

image-20230916215633503

在创建表时,如果相同的列类型,不同表列的顺序是否会影响数据库占用空间大小?使用oracle、mysql或postgresql是不是相同的表现呢? 不是的Postgresql近期发现空间使用会因为columns的顺序而占用不同的大小,当然也和实际的数据有关,简单的测试。

Oracle

SQL> CREATE TABLE t_test ( i1 int,
i2 int,
i3 int,
v1 varchar(100),
v2 varchar(100),
v3 varchar(100)7  );Table created.INSERT INTO t_test SELECT 10, 20, 30,
'abcd', 'abcd', 'abcd'3  FROM dual connect by rownum<=10000; 10000 rows created.SQL> select BYTES from dba_segments where segment_name='T_TEST';BYTES
----------393216SQL> SELECT dbms_xplan.FORMAT_SIZE(BYTES) SEG_SIZE from dba_segments where segment_name='T_TEST';SEG_SIZE
------------------------------
384KSQL> DROP TABLE T_TEST;
Table dropped.SQL> CREATE TABLE t_test ( v1 varchar(100),
i1 int,
v2 varchar(100),
i2 int,
v3 varchar(100),
i3 int7  );Table created.SQL> INSERT INTO t_test SELECT 'abcd', 10, 'abcd',
20, 'abcd', 303  FROM dual connect by rownum<=10000; SQL> select BYTES from dba_segments where segment_name='T_TEST';BYTES
----------393216

Note:
在ORACLE数据库中TABLE COLUMN顺序打乱后, 表段大小一致。

MySQL

mysql> create table t_test( i1 int,i2 int, i3 int,v1 varchar(100),v2 varchar(100),v3 varchar(100));
Query OK, 0 rows affected (0.09 sec)mysql> DELIMITER $$
mysql> CREATE PROCEDURE LoadCal()-> BEGIN->     declare n int default 1;->     declare MAX int default 10001;->     while n < MAX do ->         insert into t_test select 10,20,30,'abcd','abcd','abcd';->         set n = n + 1;->     end while;-> END$$
Query OK, 0 rows affected (0.02 sec)mysql> DELIMITER ;
mysql> select count(*) from t_test;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)mysql> call LoadCal();
Query OK, 1 row affected (1 min 17.73 sec)mysql> select count(*) from t_test;
+----------+
| count(*) |
+----------+
|    10000 |
+----------+
1 row in set (0.05 sec)mysql> SELECT TABLE_NAME  ,-> CONCAT(ROUND((DATA_LENGTH)/1024,2),'KB') AS'total'->  FROM information_schema.TABLES WHERE TABLE_NAME='t_test';
+------------+-----------+
| TABLE_NAME | total     |
+------------+-----------+
| t_test     | 1552.00KB |
+------------+-----------+
1 row in set (0.00 sec)mysql> drop table t_test;
Query OK, 0 rows affected (0.04 sec)mysql> create table t_test(  v1 varchar(100),i1 int, v2 varchar(100),i2 int,v3 varchar(100),i3 int);
Query OK, 0 rows affected (0.05 sec)mysql> drop procedure LoadCal;
Query OK, 0 rows affected (0.03 sec)mysql> DELIMITER $$
mysql> CREATE PROCEDURE LoadCal()-> BEGIN->     declare n int default 1;->     declare MAX int default 10001;->     while n < MAX do ->         insert into t_test select 'abcd',10,'abcd',20,'abcd',30 ;->         set n = n + 1;->     end while;-> END$$
Query OK, 0 rows affected (0.02 sec)mysql> DELIMITER ;
mysql> call LoadCal;
Query OK, 1 row affected (1 min 15.33 sec)mysql> SELECT TABLE_NAME  ,-> CONCAT(ROUND((DATA_LENGTH)/1024,2),'KB') AS'total'->  FROM information_schema.TABLES WHERE TABLE_NAME='t_test';
+------------+-----------+
| TABLE_NAME | total     |
+------------+-----------+
| t_test     | 1552.00KB |
+------------+-----------+
1 row in set (0.00 sec)

Note:
MySQL数据库,表列不同的顺序,表所占用空间大小也是一致。

PostGreSQL

anbob=# CREATE TABLE t_test ( i1 int,
anbob(# i2 int,
anbob(# i3 int,
anbob(# v1 varchar(100),
anbob(# v2 varchar(100),
anbob(# v3 varchar(100)
anbob(# );
CREATE TABLE
anbob=# INSERT INTO t_test SELECT 10, 20, 30,
anbob-# 'abcd', 'abcd', 'abcd'
anbob-# FROM generate_series(1, 10000);
INSERT 0 10000
anbob=# select pg_relation_size('t_test');pg_relation_size
------------------606208
(1 row)anbob=# select pg_size_pretty( pg_relation_size('t_test'));pg_size_pretty
----------------592 kB
(1 row)anbob=# drop table t_test;
DROP TABLE
anbob=# CREATE TABLE t_test ( v1 varchar(100),
anbob(# i1 int,
anbob(# v2 varchar(100),
anbob(# i2 int,
anbob(# v3 varchar(100),
anbob(# i3 int
anbob(# );
CREATE TABLE
anbob=# INSERT INTO t_test SELECT 'abcd', 10, 'abcd',
anbob-# 20, 'abcd', 30
anbob-# FROM generate_series(1, 10000);
INSERT 0 10000
anbob=# select pg_size_pretty( pg_relation_size('t_test'));pg_size_pretty
----------------672 kB
(1 row)

Note:

在PostgreSQL数据中,尽管表中的数据完全相同,但该表已显着增长。

这个问题的原因称为alignment(对齐)。

PostgreSQL tuple内部有ALIGN机制,因此字段顺序也有讲究,选择不好,可能因为ALIGN导致空间放大, 理论如下:

如果一个字段没有以CPU word-size的倍数开始,那么 CPU 就会遇到困难,在代码src/backend/access/common/heaptuple.c。

因此,PostgreSQL 会相应地在物理上对齐数据。 这里最重要的一点是,将具有相似数据类型的列彼此相邻分组是有意义的。

当然,结果和潜在的大小差异在很大程度上取决于内容。 如果在此示例中使用“abc”而不是“abcd”,则结果不会显示任何差异;

weejar=#  select pg_column_size(row(int4 '10',varchar 'abc',int4 '10',varchar 'abc'));pg_column_size
----------------40
-- 24+4+4+4+4weejar=#   select pg_column_size(row(int4 '10',int4 '10',varchar 'abc',varchar 'abc'));pg_column_size
----------------40

typalign char

typalign is the alignment required when storing a value of this type. It applies to storage on disk as well as most representations of the value inside PostgreSQL. When multiple values are stored consecutively, such as in the representation of a complete row on disk, padding is inserted before a datum of this type so that it begins on the specified boundary. The alignment reference is the beginning of the first datum in the sequence. Possible values are:

  • c = char alignment, i.e., no alignment needed.
  • s = short alignment (2 bytes on most machines).
  • i = int alignment (4 bytes on most machines).
  • d = double alignment (8 bytes on many machines, but by no means all).
weejar=# select pg_column_size(row(varchar 'abc'));pg_column_size
----------------28
weejar=#   select pg_column_size(row(int4 '10'));pg_column_size
----------------28
weejar=# select pg_column_size(row(varchar 'abcd'));pg_column_size
----------------29
weejar=# select pg_column_size(row(varchar 'abcd',int4 '10'));pg_column_size
----------------36

Note:
36= header + “abcd” 5 取4倍数为8+int4 4
= 24+4+[1+(3补齐)}+4

在C或Go Lang开发对象中同样存在该设计,如GO

image-20230916220824213

查看这个表的对齐规则

SELECT a.attname, t.typname, t.typalign, t.typlen
FROM pg_class c
JOIN pg_attribute a ON (a.attrelid = c.oid)
JOIN pg_type t ON (t.oid = a.atttypid)
WHERE c.relname = 'xxx'
AND a.attnum >= 0
ORDER BY a.attnum;

Summary

测试发现目前只有postgresql会因为补齐问题,在相同数据不同的列顺序时会产生不同的空间大小,而oracle和MySQL不存在,所以在PostgreSQL中注意列顺序,同时在opengauss系也和PG相同的表现。

by the way, 对于10000行相同的数据也可以看出三个数据库的磁盘空间耗费排列 MySQL (1500K)> PostgreSQL (600K) > Oracle (300K)

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

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

相关文章

Fizz Buzz 经典问题 - 蓝桥杯

基础知识要求&#xff1a; Java&#xff1a;方法、if else语句、算术运算符、逻辑运算符、Scanner类 Python&#xff1a; 方法、if else语句、算术运算符、逻辑运算符、input() 题目&#xff1a; 思路解析&#xff1a; 读取输入&#xff1a; 从标准输入或其他方式读取一个整数…

DC/AC电源模块:效率与可靠性兼备的能源转换解决方案

BOSHIDA DC/AC电源模块&#xff1a;效率与可靠性兼备的能源转换解决方案 随着科技的迅速发展和人工智能技术的逐渐成熟&#xff0c;各种电子设备的需求也日益增加。然而&#xff0c;这些设备往往需要不同的电压和电流来正常工作&#xff0c;而供电方式却可能不尽相同。这时&am…

单元测试,一直转圈,既不报错也不运行结束(ssm junit4 test )

修改dataSource.properties文件 然后把mysql.version的版本修改为8.x.x 如果没有效果&#xff0c;再看看连接数据库的用户名和密码是否正确&#xff0c;一般是连接数据库出了错&#xff0c;单元测试才回一直转圈&#xff0c;我是检查了一上午才发现&#xff0c;用户名错了。 检…

一天跌20%,多只可转债“腰斩”,近百只跌破面值,“退可守”的香饽饽为何破防?

专业人士指出&#xff0c;近期部分可转债大跌原因主要有两点&#xff1a;一方面&#xff0c;转债市场与权益市场联动性强。另一方面&#xff0c;近期公布的宏观经济数据稳中趋缓&#xff0c;“供强需弱”特征依然明显&#xff0c;证监会主席吴清发言及“科创板八条”新规延续了…

在举办数字化营销活动前该如何做客户画像和制定营销方案

在当今数字化时代&#xff0c;举办成功的营销活动离不开对客户的精准了解。而根据产品属性来描绘客户画像&#xff0c;并据此制定营销方案&#xff0c;是提高营销效果的关键。 一、产品属性分析 首先&#xff0c;咱们得好好琢磨一下产品本身。比如说&#xff0c;如果是一款…

基于幅值判断的工频故障分量距离保护

统的继电保护原理是基于工频电气量的&#xff0c;但近年来&#xff0c;反应故障分量的高速继电保护原理在微机保护装置中被广泛应用。故障分量只在设备发生故障时才出现&#xff0c;因此可以用叠加原理来分析其特征。 将电力系统发生的故障视为非故障状态与故障附加状态的叠加…

数据产品赋能数字化转型

数据产品赋能数字化转型 引言:数据产品的创新与发展:赋能决策智能化的钥匙一、数据产品的定义与特征二、数据产品的核心功能三、应用实践与案例分析四、未来展望引言:数据产品的创新与发展:赋能决策智能化的钥匙 在数字化转型的浪潮下,数据已成为企业核心竞争力的关键要素…

Http客户端-Feign 学习笔记

作者介绍&#xff1a;计算机专业研究生&#xff0c;现企业打工人&#xff0c;从事Java全栈开发 主要内容&#xff1a;技术学习笔记、Java实战项目、项目问题解决记录、AI、简历模板、简历指导、技术交流、论文交流&#xff08;SCI论文两篇&#xff09; 上点关注下点赞 生活越过…

6.26.1 残差卷积变压器编码器的混合工作流程用于数字x线乳房x光片乳腺癌分类

基于残差卷积网络和多层感知器变压器编码器(MLP)的优势&#xff0c;提出了一种新型的混合深度学习乳腺病变计算机辅助诊断(CAD)系统。利用骨干残差深度学习网络创建深度特征&#xff0c;利用Transformer根据自注意力机制对乳腺癌进行分类。所提出的CAD系统具有识别两种情况乳腺…

索引:通往高效查询的桥梁(五)

引言 上一章&#xff0c;我们探索了SQL的基础知识&#xff0c;从DDL、DML到DQL&#xff0c;掌握了构建和操作数据库的基本技能。现在&#xff0c;我们将目光转向数据库性能的核心——索引。索引&#xff0c;犹如图书馆中的目录系统&#xff0c;极大地加速了数据检索过程&#…

等保1.0与2.0:物理环境安全的演进之路

在信息安全的大厦中&#xff0c;物理环境安全是那坚实的基础&#xff0c;承载着整个信息系统的稳定与安全。随着时间的推移&#xff0c;我国的信息安全等级保护标准也在不断地进化与完善&#xff0c;从等保1.0到等保2.0&#xff0c;不仅仅是数字上的递增&#xff0c;更是对物理…

通用后台管理系统(一)——项目介绍

目录 二、文档结构 src文件夹&#xff1a; 三、技术和插件 1、Vue router 2、element-ui框架 3、样式插件less 4、vuex状态管理 5、axios.js 6、mock.js模拟数据 7、echarts图表工具 四、项目效果展示 总结 一、项目介绍 通用后台管理是采用vue2cli开发的项目&#…

Sql审核平台Archery的搭建和简单配置

Sql审核平台Archery的搭建和简单配置 Archery是一个开源的Web应用&#xff0c;基于Python开发&#xff0c;利用Flask作为后端框架&#xff0c;前端采用Vue.js&#xff0c;构建了一个现代化的数据操作界面。提供了SQL审核、数据查询、报表生成等功能&#xff0c;同时支持多种数据…

async异步函数

文章目录 异步函数&#xff08;用 async 声明的函数&#xff09;异步函数的返回值async/await 的使用异步函数的异常处理总结 感谢铁子阅读&#xff0c;觉得有帮助的话点点关注点点赞&#xff0c;谢谢&#xff01; 异步函数&#xff08;用 async 声明的函数&#xff09; 异步函…

yolov8部署资料

1.labelImg安装&#xff1a; labelImg的安装过程可以参照以下步骤进行&#xff0c;这里以Windows操作系统为例&#xff1a; 1. 检查Python环境 首先&#xff0c;需要确认你的电脑上是否已经安装了Python。你可以通过Win R打开windows“运行”对话框&#xff0c;输入cmd&#x…

瑶池数据库SQL-问题二的解决方案

瑶池数据库SQL-问题二的解决方案 为什么选问题二问题二准备工作解决方案第一步第二步初步尝试再次尝试主表自关联查询满足条件数据 解题感受 为什么选问题二 个人没有详细的看三个题目的具体内容&#xff0c;只是看了三个题目的题目名称&#xff0c; 最后觉得问题二比较有意思…

1.1 离散信号的时域分析

目录 基本离散信号 单位脉冲序列δ[k] 单位阶跃序列u[k] 矩形序列Rn[k] 实指数序列x[k] 虚指数序列和正弦序列x[k] 基本运算 翻转 位移 抽取 内插 卷积 相关 DSP&#xff08;Digital Signal Processing&#xff09; 数字信号处理 基本离散信号 单位脉冲序…

目标检测系列(四)利用pyqt5实现yolov8目标检测GUI界面

目录 1、pyqt5安装 2、PyCharm添加Qt Designer、PyUIC 3、Qt Designer设计界面 4、根据ui文件自动生成py文件 5、修改py文件来调用检测程序 6、执行py文件启动 1、pyqt5安装 Qt Designer&#xff1a;一个用于创建图形用户界面的工具&#xff0c;可轻松构建复杂的用户界面…

还在花钱做数据可视化?为大家推荐一款免费可视化工具

在当今数据驱动的世界里&#xff0c;数据可视化已经成为不可或缺的工具&#xff0c;帮助我们更好地理解和分析信息。然而&#xff0c;许多企业和个人仍在为昂贵的可视化软件买单&#xff0c;承受着高昂的费用和复杂的操作流程。因此&#xff0c;作为一个经常接触数据可视化的相…

php聚合快递寄快递小程序

一、引言&#xff1a;告别传统寄件&#xff0c;拥抱便捷新选择 在数字化时代&#xff0c;我们越来越追求便捷和高效。传统的寄件方式已经无法满足现代人快速、便捷的需求。因此&#xff0c;一款聚合快递优惠寄件小程序应运而生&#xff0c;它集合了多家快递公司&#xff0c;为…