MySQL table size 远远大于其中的数据大小,导致索引扫描查询变慢
MySQL table size much larger than size of data in it, causing index scanning queries to be slow
我有一个 table 插入和删除的频率很高。行数永远不会超过几百,我不希望它超过几兆字节,但是 table 大小是 20 GB 并且还在增长。它使用 MySQL 5.6.35,引擎是 InnoDB。我希望插入的行插入到删除行留下的 space 中,但事实并非如此。它在一周内增长到这个水平,在某个时候似乎启动了一些后台进程,并慢慢将其减少了几千兆字节。
table 太大的问题是它会导致扫描整个 table 的任何查询(如 count(*)
运行 非常慢)。
我可以做些什么来防止 table 像这样增长吗?
在此 table 上尝试优化 TABLE。
OPTIMIZE TABLE reorganizes the physical storage of table data and
associated index data, to reduce storage space and improve I/O
efficiency when accessing the table. The exact changes made to each
table depend on the storage engine used by that table.
InnoDB 会在您删除时释放 space,但不会立即释放。它很快将记录标记为已删除,但 space 稍后被清除线程标记为空闲。如果您继续快速插入更多数据,您可能会导致 InnoDB 至少在部分时间扩展 tablespace,因为您试图重用已删除的 space清除之前的行。
例如阅读:
- https://dev.mysql.com/doc/refman/5.6/en/innodb-improved-purge-scheduling.html
- https://dev.mysql.com/doc/refman/5.6/en/innodb-multi-versioning.html
If you insert and delete rows in smallish batches at about the same rate in the table, the purge thread can start to lag behind and the table can grow bigger and bigger because of all the “dead” rows, making everything disk-bound and very slow. In such a case, throttle new row operations, and allocate more resources to the purge thread by tuning the innodb_max_purge_lag system variable. See Section 14.14, “InnoDB Startup Options and System Variables” for more information.
我从未遇到过设置 innodb_max_purge_lag
的网站,因为这意味着它们对数据库的持续写入有时会变慢。他们通常不希望这样。
相反,我所做的是设置 innodb_purge_threads=4
而不是默认值 1。这有助于清除在运行时快速行动。
如果您的应用程序保持事务处于打开状态,需要保留那些已删除的行以满足其对数据库的可重复读取视图,则清除会进一步延迟。如果打开事务的快照要求阻止了清除,则清除速度有多快或必须执行清除的线程数都没有关系。
您应该及时提交交易,而不是让它们无限期地打开。或者将您的事务隔离级别更改为 READ-COMMITTED,这样您的事务就不需要数据库来保留旧记录版本。
我有一个 table 插入和删除的频率很高。行数永远不会超过几百,我不希望它超过几兆字节,但是 table 大小是 20 GB 并且还在增长。它使用 MySQL 5.6.35,引擎是 InnoDB。我希望插入的行插入到删除行留下的 space 中,但事实并非如此。它在一周内增长到这个水平,在某个时候似乎启动了一些后台进程,并慢慢将其减少了几千兆字节。
table 太大的问题是它会导致扫描整个 table 的任何查询(如 count(*)
运行 非常慢)。
我可以做些什么来防止 table 像这样增长吗?
在此 table 上尝试优化 TABLE。
OPTIMIZE TABLE reorganizes the physical storage of table data and associated index data, to reduce storage space and improve I/O efficiency when accessing the table. The exact changes made to each table depend on the storage engine used by that table.
InnoDB 会在您删除时释放 space,但不会立即释放。它很快将记录标记为已删除,但 space 稍后被清除线程标记为空闲。如果您继续快速插入更多数据,您可能会导致 InnoDB 至少在部分时间扩展 tablespace,因为您试图重用已删除的 space清除之前的行。
例如阅读:
- https://dev.mysql.com/doc/refman/5.6/en/innodb-improved-purge-scheduling.html
- https://dev.mysql.com/doc/refman/5.6/en/innodb-multi-versioning.html
If you insert and delete rows in smallish batches at about the same rate in the table, the purge thread can start to lag behind and the table can grow bigger and bigger because of all the “dead” rows, making everything disk-bound and very slow. In such a case, throttle new row operations, and allocate more resources to the purge thread by tuning the innodb_max_purge_lag system variable. See Section 14.14, “InnoDB Startup Options and System Variables” for more information.
我从未遇到过设置 innodb_max_purge_lag
的网站,因为这意味着它们对数据库的持续写入有时会变慢。他们通常不希望这样。
相反,我所做的是设置 innodb_purge_threads=4
而不是默认值 1。这有助于清除在运行时快速行动。
如果您的应用程序保持事务处于打开状态,需要保留那些已删除的行以满足其对数据库的可重复读取视图,则清除会进一步延迟。如果打开事务的快照要求阻止了清除,则清除速度有多快或必须执行清除的线程数都没有关系。
您应该及时提交交易,而不是让它们无限期地打开。或者将您的事务隔离级别更改为 READ-COMMITTED,这样您的事务就不需要数据库来保留旧记录版本。