The data size for InnoDB on disk is usually 2-3 times larger than you could calculate. It's connected with
- Column Overhead (Length)
- Overhead per line (tx id, etc.)
- Block overhead (16 KB) (link to next block - Tree B +)
- Weighted average rates of 69% are filled.
- MVCC - managing multiple versions of Concurrency. This means that there may be old and new copies of any row coexisting at the same time during the transaction.
- Etc.
One thing that could help: Almost an application does not require a BIGINT
(8 bytes) for identifiers. Consider INT UNSIGNED
(4 bytes, 4B limit) or MEDIUMINT UNSIGNED
(3 bytes, 16M limit), etc. You have 2 Bigints, but 4 copies of them - the secondary key implicitly includes PK columns.
PRIMARY KEY
is stored with data, so it carries very little overhead. An additional key, which is actually 4 columns, is BTree with a similar set of overhead.
Even MyISAM has overhead:
- At least 1 byte per line. (1 in your case)
- 1 byte for 8 columns
NULLable
(in your case there is not a single one) - Some amount of lost space after the
DELETEd
or UPDATEd
. (Updated will not be a problem in your case due to the size of the FIXED
record.) PRIMARY KEY
is like any other index- All keys have a 69% problem; 1KB blocks
(Since you do not have VARCHAR
or TEXT
, I do not need to discuss the `CHARACTER SET.) Problems.)
In InnoDB, SHOW TABLE STATUS
often turned off 2 times in estimating the number of rows. Avg_row_length is calculated as Data_length / Rows, so it is usually disabled.
I do not recommend OPTIMIZE TABLE
for InnoDB tables; it's almost always worth the effort.
When ALTER TABLE .. ADD INDEX ..
executed, older versions of MySQL will rebuild the entire table and indexes. In doing so, you get the OPTIMIZE
effect. (It is unlikely, but not impossible, to increase the size of the data.) Newer versions only add to the new index. What version are you working in?
Each INDEX
is a separate BTree (except PK in InnoDB) (and except FULLTEXT
and FULLTEXT
).
source share