Mysql

主鍵的大小是否會影響表的大小?

  • June 17, 2013

我有一個表(InnoDB),數據長度約為 36G,索引長度為 23G。

它有一個跨三列的複合主鍵。

作為減小該表大小的最初嘗試,我刪除了主鍵(實際上並不需要)。然而,數據長度和索引長度是相同的。

這是可以預料的嗎?

在此數據庫上啟用了更新innodb_file_per_table

更新

mysql> show create table event;

CREATE TABLE `event` (
`owner_id` varchar(36) NOT NULL,
`key_id` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
KEY `owner_id_idx` (`owner_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 

簡短的回答

實際上是相反的:表的大小會影響主鍵的大小。因此,是的,這是意料之中的。

長答案

主鍵位於gen_clust_index中,也就是聚集索引。

根據MySQL Documentation on the Clustered Index

聚集索引如何加速查詢

通過聚集索引訪問行速度很快,因為行數據位於索引搜尋引導的同一頁上。如果表很大,與使用與索引記錄不同的頁面儲存行數據的儲存組織相比,聚集索引架構通常會節省磁碟 I/O 操作。(例如,MyISAM 將一個文件用於數據行,將另一個文件用於索引記錄。)

根據這個描述,InnoDB 儲存引擎的每一行都位於聚集索引內。

鑑於此,需要回答兩個問題:

  1. 為什麼刪除 PRIMARY KEY 不會縮小聚集索引?
  2. 為什麼 OPTIMIZE TABLE 不收縮聚集索引?

這兩個問題的答案都只有一個。關於聚集索引的 MySQL 文件說:

如果表沒有 PRIMARY KEY 或合適的 UNIQUE 索引,InnoDB 在內部生成一個隱藏的聚集索引,該索引包含行 ID 值的合成列。這些行按 InnoDB 分配給此類表中的行的 ID 排序。行 ID 是一個 6 字節的欄位,隨著新行的插入而單調增加。因此,按行 ID 排序的行在物理上是按插入順序排列的。

想一想:OPTIMIZE TABLE由於您沒有嘗試刪除任何行,因此變得無效。由於您沒有刪除任何行,因此行佔用的所有空間仍將位於聚集索引內。您只需將一個密鑰(您的主密鑰)換成另一個(6 字節行 ID)。

縮小聚集索引的方法有哪些?

我有您可能需要做的三 (3) 種技術之一

技巧#1:減少你的列的長度

  • 縮小INTs到 SMALLINT 或 TINYINT
  • 縮小VARCHAR(255)VARCHAR(128)

技巧#2:刪除舊行

  • 查找具有非常舊時間戳的行,然後

    • 刪除舊行
    • 將舊行存檔在另一個表中

技巧#3:從表中刪除列

  • 這在理論上是正確的
  • 沒有人願意在流程中失去數據
  • 在刪除列之前存檔表

警告

在應用這三 (3) 種技術之一之前,請備份您的表

結語

一旦應用了這三 (3) 種技術中的一種,您就可以執行以下操作之一來縮小聚集索引(例如,mydb.mytable):

  • OPTIMIZE TABLE mydb.mytable;
  • ALTER TABLE mydb.mytable ENGINE=InnoDB;

試一試 !!!

更新 2013-06-17 07:34 EDT

這是你的最後一條評論

因此,如果原始主鍵大於 6 字節,我不會期望看到聚集索引大小減少嗎?

即使PRIMARY KEY是 now CHAR(255),每一行都位於聚集索引內。InnoDB 中的每個頁面是 16K。6 字節的行 ID(InnoDB 仍然在內部使用)仍然嵌入在相同的頁面中。刪除PRIMARY KEY它更像是一種邏輯刪除而不是物理刪除。這就是為什麼我之前說

您只需將一個密鑰(您的主密鑰)換成另一個(6 字節行 ID)

刪除的物理行為PRIMARY KEY可能需要在墓碑(標記)每一行時執行到每一行,而不是使用一些內部列組合,PRIMARY KEY而是恢復到行 ID。這幾乎不會改變 16K InnoDB 頁面的使用,無論行長度是長的(可能允許頁面中的幾行)或短的(可能允許頁面中的更多行)。

執行OPTIMIZE TABLE縮小它仍然不會產生任何明顯的變化,因為聚集索引的標記機制仍然存在。給定表中行的平均長度,完全相同的行數使聚集索引保持相同的大小。

查看我之前提到的三種技術以及MySQL Documentation on the Clustered Index。鑑於表中的行數和您目前的表定義,如果您無法減小列大小、刪除列、刪除行並將它們歸檔到其他地方,那麼您無法縮小表。

引用自:https://dba.stackexchange.com/questions/44520