When you delete a record, you are simply warning that that space is free.
It would be impractical for a DB to keep shortening the file in production as this would mean rearranging all the data internally (similarly to a disk defragmentation).
If you really need it, somehow you need to "reassemble" the table.
Solution built-in to Innodb and Myisam
Mysql has the OPTIMIZE TABLE
, which, among other things, reorganizes the data internally:
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...
It works for most uses, and the behavior changes somewhat between Innodb and Myisam. It doesn’t work for others Engines, keep this in mind.
https://dev.mysql.com/doc/refman/5.7/en/optimize-table.html
"Manual" solution for general or "controlled use":
If it is a bank that can be stopped for an instant, one solution is simply to make a dump of the table and recreate it by importing the same data:
BACK UP AND TEST BACKUP BEFORE TRYING THIS!
mysqldump db_name t1 > dump.sql
mysql db_name < dump.sql
To do in all tables:
mysqldump --all-databases > dump.sql
mysql < dump.sql
If you need to keep DB in production, an intermediate solution is to create a table with the same structure, and use a
SELECT * FROM tabela INSERT tabela2
and at the end, rename the tables, then discard the old.
The precaution, in this second case, is that you need to find a way to lock the original against writing, because someone can insert or modify a data while INSERT is taking place. This second solution is best suited when you can block writing but need to keep reading.
The database does not reallocate memory when you delete a record.
– LucaoA