2015-11-24 30 views
3

我有一个数据库跟踪用户状态的单个表。当我完成处理该行时,不再需要将其保存在数据库中并可以删除。查询性能是否从删除SQL数据库中的行增加?

现在让我们说我想跟踪行而不是删除它(用于历史目的,分析等)。它会更好于:

  1. 在同一个表保留数据和标记行作为“拿来主义”(有一个额外的列或类似的东西)

  2. 从表中删除的行将其插入到只创造了历史目的

对于选择#1一个单独的表,我不知道是否留在数据库中的不必要的行会开始影响查询性能。 (我所有的查询都在索引列上,所以也许这并不重要?)

对于选择#2,我想知道是否不断删除行最终会导致诸如碎片之类的问题?

+0

嗯,这是MySQL的。不应该标记两者。 – jnortey

+0

对于选择#2而不是在将行转移到另一个表之后删除行 - 您是否可以不重用它们。将行标记为不再使用,并在您需要跟踪当前状态并首先找到使用时搜索那些行 - 如果没有添加额外的记录。这样你就可以避免碎片。不要说这是一个很好的解决方案 - 只是一种避免碎片的方法,如果你沿着这条路线走下去的话。 – PaulF

+0

感谢PaulF的建议,但是我想尽可能避免重复数据。 – jnortey

回答

3

查询性能将是从长远来看好:

什么,直到永远发生插入:

表的增长,指数增长,指数的表现(查找)是的尺寸减小表格,特别是插入性能受到伤害。

什么用delete发生的事情:

表网页获得支离破碎,所以删除的空间不重复使用100%符合市场预期,更接近50%,在MySQL。所以这个表格仍然会增长到您预期数据量的两倍。索引被分割并成为大片:它包含您的新数据,但也包含旧数据的结构。这取决于你的数据结构有多糟。然而,这种情况稳定在一定的表现。这一业绩点有2个好处:

1)表的大小是比较有限的,所以潜在的全表扫描速度更快

2)你的表现是可以预见的。

由于存在碎片,但此性能点不等于您的数据量的两倍左右,所以它往往会变得更糟(以自己为基准)。然而,删除方案的好处在于您的数据集较小,因此您可以在每个合理的时间段内重建一次索引,从而提高性能。

替代

有两个备选方案,你可以看看,以提高性能:

  • 切换到MariaDB的:这个收益对大数据集约8%的性能(我的观察,数据集只有大约200GB的压缩数据)

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

+0

我比空间更担心查询性能。如果空间不是问题,你会说选项#2是更好的选择吗?如果我的阅读正确,查询性能并不像选项2那样糟糕。 – jnortey

+0

我会使用常量删除或分区。你的数据结构如何?主键等(用这个更新你的问题并发送消息,然后我会看看那个场景)。 –

1

如果大部分表是标记为删除,你会为你寻找非删除的记录绊倒他们。将is_deleted添加到许多索引可能会有所帮助。

如果您是纯粹在年龄删除记录,然后PARTITION BY RANGE(TO_DAYS(...))是一个很好的方式来建立表。 DROP TABLE是即时的,ALTER TABLE ... REORGANIZE ...创建新的一周(或月或......)分区也是即时的。详情请参阅my blog

如果您将“移动”记录添加到另一个表中,则由于存在碎片,表格不会收缩很快。如果你有足够的磁盘空间,这不是一个错误处理。如果某些查询需要查看当前和归档记录,请使用UNION ALL;它非常容易和高效。