列順序占用存儲大小的影響 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.pswp.cn/diannao/36152.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36152.shtml
英文地址,請注明出處:http://en.pswp.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…

NIST網絡安全框架體系應用

NIST網絡安全框架體系應用 NIST網絡安全框架&#xff08;NIST Cybersecurity Framework, NIST CSF&#xff09;由美國國家標準與技術研究院&#xff08;NIST&#xff09;發布&#xff0c;是一套廣泛應用于各種組織的網絡安全管理指南。該框架通過識別、保護、檢測、響應和恢復…

單元測試,一直轉圈,既不報錯也不運行結束(ssm junit4 test )

修改dataSource.properties文件 然后把mysql.version的版本修改為8.x.x 如果沒有效果&#xff0c;再看看連接數據庫的用戶名和密碼是否正確&#xff0c;一般是連接數據庫出了錯&#xff0c;單元測試才回一直轉圈&#xff0c;我是檢查了一上午才發現&#xff0c;用戶名錯了。 檢…

Redis 數據類型和各自的使用場景

Redis 數據類型和各自的使用場景 1、String類型2、List類型3、Hash類型4、Set類型5、Zset類BitMap&#xff1a;HyperLogLog&#xff1a;GEO&#xff1a;.Stream&#xff1a;跳表 常見的有五種數據類型&#xff1a;String字符串&#xff0c;List列表&#xff0c;Hash哈希&#x…

一天跌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;極大地加速了數據檢索過程&#…

cmd設置編碼為utf8

文章目錄 臨時設置永久設置(通過注冊表) cmd命令亂碼&#xff0c;解決方案比較簡單。 輸入chcp&#xff0c; 如果返回的是936&#xff0c;通常是GBK或CP936。 如果返回的是65001&#xff0c;表示是UTF-8。 臨時設置 chcp 65001 # 設置 chcp # 查看 永久設置(通過注冊表) 打…

等保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開發的項目&#…

QLibrary::load、QPluginLoader::instance加載錯誤

現象 在使用pluginLoader.instance()總是為空&#xff0c;通過pluginLoader.errorString()獲取的錯誤是 “Cannot load library xxxPlugin.dll: 找不到指定的程序。” 原因 是否缺少依賴的dll&#xff1b;依賴的dll是否在程序的運行中&#xff1b;依賴的dll的版本是否正確&am…

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; 最后覺得問題二比較有意思…