我有一个表格,可以快速插入和删除表格。行的数量从不大于几百,并且我不希望它大于几兆字节,但是表大小为20 GB,并且还在不断增长。它使用的是MySQL 5.6.35,引擎是InnoDB。我希望插入的行会插入到已删除的行剩下的空间中,但是事实并非如此。它会在一周之内增长到此级别,并且在某个时候似乎开始了一些后台进程,并逐渐将其减少了几GB。
表太大的问题是,它会导致扫描整个表的所有查询(如count(*)
)运行非常缓慢。
是否可以更改某些内容以防止表如此增长?
答案 0 :(得分:0)
尝试对此表进行优化。
OPTIMIZE TABLE重新组织表数据的物理存储并 相关的索引数据,以减少存储空间并改善I / O 访问表时的效率。对每项所做的确切更改 表取决于该表使用的存储引擎。
答案 1 :(得分:0)
InnoDB会在您删除时释放可用空间,但不会立即释放。它迅速将记录标记为已删除,但是稍后会通过清除线程将空间标记为空闲。如果您继续快速插入更多数据,则可能导致InnoDB至少在部分时间扩展表空间,因为您正试图在清除已删除的行之前重新使用它们。
例如阅读:
如果您以大约相同的速率在表中以较小的批次插入和删除行,则由于所有“死”行,清除线程可能开始滞后,并且表可能变得越来越大,从而使所有磁盘绑定并且非常缓慢。在这种情况下,请限制新行操作,并通过调整innodb_max_purge_lag系统变量来向清除线程分配更多资源。有关更多信息,请参见第14.14节“ InnoDB启动选项和系统变量”。
我从未遇到过任何设置innodb_max_purge_lag
的站点,因为这意味着有时它们对数据库的连续写入速度可能会变慢。他们通常不想要那个。
相反,我所做的是设置innodb_purge_threads=4
而不是默认值1。这有助于清除在运行时迅速采取行动。
如果您的应用程序保持打开状态并需要保留那些已删除的行以满足其REPEATABLE-READ视图的数据库事务,则清除将进一步延迟。如果打开事务的快照要求阻止了清除,则清除的速度有多快或执行清除线程的数量都没有关系。
您应立即提交交易,并且不要无限期地打开交易。或将事务隔离级别更改为READ-COMMITTED,这样您的事务就不需要数据库来保留旧的记录版本。