I have this table:
CREATE TABLE `tree_paths` (
`child_id` int(10) unsigned NOT NULL,
`parent_id` int(10) unsigned NOT NULL,
`sponsor_upline` tinyint(1) NOT NULL DEFAULT '0',
`left_leg` tinyint(1) NOT NULL,
`binary_level` smallint(5) unsigned NOT NULL DEFAULT '0',
`sponsor_level` smallint(5) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`child_id`,`parent_id`),
KEY `tree_paths_parent_id_foreign` (`parent_id`),
CONSTRAINT `tree_paths_child_id_foreign` FOREIGN KEY (`child_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `tree_paths_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
An int(10)
consumes 4 Byte, a smallint(5)
2 Byte, a tinyint(1)
1 Byte. Thus, one row raw data should be 14 Byte.
I have ~16 Million rows inserted. For some reason the AVG row length is 57 Byte instead of 14 Byte.
Is it realistic, that the B-tree for the primary tuple key uses 3 times as much storage as the data itself?
In addition, I have read in https://stackoverflow.com/a/30318725/2311074 that
the primary key is already accounted in the DATA_LENGTH. INDEX_LENGTH means "the size of all secondary indexes".
If that is true, then why is index_length 1/4 of the total size? AS one can see above, I have no secondary keys. Or does it come from the FOREIGN
keys?
Remarks:
I found similar questions to mine.
One is Why is InnoDB table size much larger than expected? but it is 10 years old and I don't get it at all. The answer of that question is that a hidden 6-byte column is the reason for the discrepancy there. However, the discrepancy is not 6 but 36. And the user did not use any key, still Index_length is huge. So I have no idea how any of that makes sense, but I guess 10 years ago things were maybe different.
Another answer that I found was at Average row length higher than possible. The point in this answer is that InnoDb just allocated more space then it needs. However, when I check show table status
I see that I have 7.3 MB free left. So it seems I can dismiss this.