我在
MySql服务器中有一个表,该表包含大约1M行.仅因为一个列表每天占用更多磁盘空间.此列的数据类型为Mediumblob.表大小约为90 GB.
在每行插入之后,我做了一些处理然后我真的不需要这个列.
因此对于此列,如果我在处理行后将值设置为NULL,MySql是否利用此空白空间进行下一行插入?
MySql Server详细信息
服务器版本:5.7
引擎:InnoDB
托管:Google Cloud Sql
编辑1:
我从表中删除了90%的行,然后运行了OPTIMIZE TABLE table_name
但它只减少了4GB的磁盘空间,并且没有回收可用磁盘空间.
编辑2
我甚至删除了我的数据库并创建了新的数据库和表,但MySql服务器仍然显示80GB的磁盘空间. MySQL服务器的所有数据库的大小
SELECT table_schema "database name",
sum( data_length + index_length ) / 1024 / 1024 "database size in MB",
sum( data_free )/ 1024 / 1024 "free space in MB"
FROM information_schema.TABLES
GROUP BY table_schema;
+--------------------+---------------------+------------------+
| database name | database size in MB | free space in MB |
+--------------------+---------------------+------------------+
| information_schema | 0.15625000 | 80.00000000 |
| app_service | 15.54687500 | 4.00000000 |
| mysql | 6.76713467 | 2.00000000 |
| performance_schema | 0.00000000 | 0.00000000 |
| sys | 0.01562500 | 0.00000000 |
+--------------------+---------------------+------------------+
谢谢
最佳答案 编辑:从下面的评论中可以看出,用户的二进制日志是罪魁祸首.有意义的是,在很多DELETE之后二进制日志会很大,并且假设MySQL实例使用基于行的复制.
答案很复杂.
您可以使用NULL而不是实际值来节省空间.对于详细信息,InnoDB每行仅使用1位来指示该值为NULL(请参阅我对https://stackoverflow.com/a/230923/20860的旧答案).
但这只会在存储该行的页面中留出空间.每个页面只能存储同一个表中的行.因此,如果将其中的一组设置为NULL,则会在该页面中创建空间,该空间仅可用于该表的后续插入.它不会使用属于其他表的行的间隙.
并且它仍然可能不会被重用于mediumblob表的任何行,因为InnoDB以主键顺序存储行.给定表的页面不必是连续的,但我猜测页面中的行可能是连续的.换句话说,您可能无法在页面中的主键随机顺序中插入行.
我肯定不知道这个细节,你必须阅读Jeremey Cole’s research on InnoDB storage才能知道答案.这是一段摘录:
The actual on-disk format of user records will be described in a future post, as it is fairly complex and will require a lengthy explanation itself.
User records are added to the page body in the order they are inserted (and may take existing free space from previously deleted records), and are singly-linked in ascending order by key using the “next record” pointers in each record header.
是否可以按顺序插入行并重用页面上的空间仍然不太清楚.
因此,您可能只会严重破坏页面,并且无论如何都会将具有高主键值的新行添加到其他页面.
如果您不时使用OPTIMIZE TABLE,您可以更好地回收空间,这将有效地将整个表重写为新页面.这可能会重新打包行,如果您将值更改为NULL,则会在每个页面中插入更多行.
删除不需要的行会更有效,然后是OPTIMIZE TABLE.这将消除整个页面,而不是让它们碎片化.