InnoDB stores data (and indexes) in 16KB blocks.
It sounds like you are shrinking each row by an average of 7% (300/4K).
If the shrinkage had been more than 50%, then probably InnoDB would have noticed adjacent half-full blocks and coalesced them, thereby freeing up some of the predicted savings. (A block is 16KB.) I say only "some" because it is not aggressive at packing the blocks after UPDATEs
or DELETEs
.
If you had not done the OPTIMIZE
, future inserts/deletes/updates, if they were scattered around the table, would have filled in the 'holes' and/or led to blocking coalescing. If, on the other hand, the main activity is to add new rows at the 'end' of the PRIMARY KEY
values, then this subsequent cleanup would not happen, and the OPTIMIZE
would be desirable.
How much did the OPTIMIZE
benefit you? Performance probably changed very little. Sure, you freed up some space, but, if you are not running out of disk space, that does not matter much.
Another issue... Tablespaces. The old default was to put all tables into a single tablespace (the file named ibdata1
). It would grow but never shrink. Any freed blocks would be available for future database work, but would not be given back to the OS.
The new default (innodb_file_per_table
) has the same problem. However, an explicit OPTIMIZE
rebuilds the table, and does give the freed space back to the OS. Caveat: During the process, you need 2x the disk space. So, if you were very tight on space, OPTIMIZE
would fail. However...
OPTIMIZE TABLE
(for InnoDB) is "Performed in-place as of MySQL 5.6.17. In-place operation is not supported for tables with FULLTEXT indexes. The operation uses the INPLACE algorithm, but ALGORITHM and LOCK syntax is not permitted. " -- https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html