通过删除 SQL 数据库中的行提高查询性能?

Query performance increase from deleting rows in SQL database?

我有一个数据库,其中有一个 table 用于跟踪用户状态。当我完成对行的处理后,不再需要将其保留在数据库中并可以将其删除。

现在假设我想跟踪该行而不是将其删除(用于历史目的、分析等)。会不会更好:

  1. 将数据保留在相同的 table 中并将该行标记为 'used'(带有额外的列或类似内容)

  2. 从 table 中删除该行并将其插入到单独的 table 中,该 table 仅为了历史目的而创建

对于选项 #1,我想知道在数据库中保留不必要的行是否会开始影响查询性能。 (我所有的查询都在索引列上,所以也许这无关紧要?)

对于选项#2,我想知道不断删除行是否最终会导致碎片等问题?

长查询性能会更好 运行:

永久插入发生了什么:

The table grows, indexes grow, index performance (lookup) is decreases with the size of the table, especially insert performance is hurt.

删除发生了什么:

Table pages get fragmented, so the deleted space is not re-used 100% as expected, more near 50% in MySQL. So the table still grows to about twice the size you might expect for your amount of data. The index gets fragmented and becomes lob sided: It contains your new data but also the structure for your old data. It depends on the structure of your data on how bad this gets. This situation however stabilizes at a certain performance. This performance point has 2 benefits:

1) The table is more limited in size, so potential full table scans are faster

2) Your performance is predictable.

Due to the fragmentation however this performance point is not equal to about twice your data amount, it tends to be a bit worse (benchmark it to see yourself). The benefit of the delete scenario is however since you have a smaller data set, that you might be able to rebuild your index once every reasonable period, thus improving your performance.

备选方案

您可以考虑两种提高性能的备选方案:

  • 切换到 MariaDB:这在大型数据集上获得了大约 8% 的性能(我的观察,数据集只有大约 200GB 的压缩数据)

  • 看分区:如果你有一个方便的分区参数,你可以为你创建一系列"small tables"并防止删除,重建和历史数据管理的逻辑。这可能会为您提供最佳性能配置文件。

如果 table 中的大部分 标记为已删除 ,您在查找未删除的记录时会被它们绊倒。在许多索引中添加 is_deleted 可能会有所帮助。

如果您纯粹根据年龄 删除记录,那么PARTITION BY RANGE(TO_DAYS(...)) 是构建table 的绝佳方式。 DROP TABLE 是瞬时的,创建新周(或月或...)分区的 ALTER TABLE ... REORGANIZE ... 也是瞬时的。有关详细信息,请参阅 my blog

如果你 "move" 记录 到另一个 table,那么 table 不会因为碎片化而很快收缩。如果你有足够的磁盘 space,这不是一个错误处理。如果某些查询需要同时查看当前记录和存档记录,请使用 UNION ALL;非常简单高效。