簡體   English   中英

為什么我的桌子尺寸比預期的大4倍? (行×字節/行)

[英]Why is my table size more than 4x larger than expected? (rows*bytes/row)

我在看MySQL中一個簡單的表,它有4列,大小如下,

unsigned bigint (8 bytes)
unsigned bigint (8 bytes)
unsigned smallint (2 bytes)
unsigned tinyint (1 byte)

所以我希望19字節/行。

此表中有1,654,150行,因此數據大小應為31,428,850字節(或大約30兆字節)。

但我可以通過phpMyAdmin看到數據占用136.3 MiB(不包括bigint 1, smallint, tinyint上的索引大小bigint 1, smallint, tinyint為79 MiB)。

存儲引擎是InnoDB,主鍵是bigint 1, bigint 2 (用戶ID和唯一的項ID)。


編輯:根據注釋中的請求,這是SHOW CREATE TABLE storage

CREATE TABLE `storage` (
 `fbid` bigint(20) unsigned NOT NULL,
 `unique_id` bigint(20) unsigned NOT NULL,
 `collection_id` smallint(5) unsigned NOT NULL,
 `egg_id` tinyint(3) unsigned NOT NULL,
 PRIMARY KEY (`fbid`,`unique_id`),
 KEY `fbid` (`fbid`,`collection_id`,`egg_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

您的索引在磁盤上有自己的表(盡管您不能直接'看到'它們)。 db的總大小是表和索引表的大小。

show create table <tablename>;

您可以看到定義的任何索引。 想象一下,添加表的總大小以及包含主鍵中兩列的表。 添加的那些,將為您提供您所看到的尺寸。

如果表經常進行插入/刪除/更新,您可能希望嘗試運行OPTIMIZE TABLE查詢以查看表可以收縮多少。 數據文件中可能存在碎片整理和未使用的空格。

phpmyadmin顯示的數據大小將不符合您的預期。 您將在第一次創建表時看到,它不會顯示數據用法:0。它將是16KB或32KB或其他東西。 插入記錄時,大小不會改變。 這就是innoDB如何控制表文件的效率。

檢查SHOW TABLE STATUS FROM {db_name}並查看表中每行的Avg_row_length的大小。 它也不會是19個字節

磁盤上InnoDB的數據大小通常是您計算的2-3倍。 這是因為

  • 每列開銷(長度,偏移到記錄)
  • 每行開銷(tx id等)
  • 每塊開銷(16KB)(鏈接到下一個塊 - B +樹)
  • BTree平均69%滿
  • MVCC - 多版本並發控制。 這意味着在事務期間可以同時存在任何行的舊副本新副本
  • 等等。

有一點可以幫助:幾乎沒有應用程序需要BIGINT (8字節)用於ID。 考慮INT UNSIGNED (4字節,4B限制)或MEDIUMINT UNSIGNED (3字節,16M限制)等。您有2個Bigint,但它們有4個副本 - 輔助密鑰隱含地包括PK列。

PRIMARY KEY與數據一起存儲,因此它產生的開銷非常小。 輔助密鑰(實際上是4列)是具有類似開銷的BTree。

即使在MyISAM中,也存在開銷:

  • 每行至少1個字節。 (在你的情況下為1)
  • 每8個NULLable列1個字節(在您的情況下沒有)
  • 行之后的一些丟失空間是DELETEdUPDATEd (由於FIXED記錄大小,在您的情況下更新不會有問題。)
  • PRIMARY KEY就像任何其他索引一樣
  • 所有密鑰都有69%的問題; 塊是1KB

(因為你沒有VARCHARTEXT ,所以我不需要討論`CHARACTER SET問題。)

在InnoDB中, SHOW TABLE STATUS在行數估計中經常偏差2倍。 Avg_row_length計算為Data_length / Rows,因此它通常是關閉的。

推薦InnoDB表的OPTIMIZE TABLE ; 它幾乎總是不值得努力。

在做ALTER TABLE .. ADD INDEX .. ,舊版本的MySQL會重建整個表和索引。 這樣做可以獲得OPTIMIZE的效果。 (數據大小增加不太可能,但並非不可能。)較新版本僅添加新索引。 你正在運行什么版本?

每個INDEX是一個單獨的BTree(InnoDB中的PK除外)(除了FULLTEXTSPATIAL )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM