我有一个贯穿许多行的cron,删除了“坏”行(根据我的标准)。我只是想知道优化脚本的最佳方法。我可以做以下其中一项:
让相同的cron在找到它们后立即删除“坏”行。
让相同的cron立即将“坏”行更新为状态“1”,这意味着不好。然后,我可以设置另一个运行一小时的cron,删除状态为“1”的所有行。为了加快速度,我猜我会有一个关于“状态”的索引,但这也可能会破坏性能。
有什么建议吗?
答案 0 :(得分:2)
具有两个可能值的字段的索引没有您想象的那么有用,特别是如果您不断更改要编制索引的字段。例如,假设您有一个包含100,000行数据的表,并且最初“status”对于每一行(在删除周期之后和更新周期之前)设置为0。在那个时间点,使用该索引相当于对表进行顺序搜索。如果更新1,000行,将其状态标记为1,则需要更新(并可能重新平衡)1,000次索引。最后,当您删除状态为== 1的所有行时,您将能够利用索引(您只查看1%的行),但您需要将索引更新1,000次(在除了删除行。)
IMO,你最好直接选择'坏'行并立即删除它们 - 你可以消除你使用不好的索引的开销,以及第二次查询的开销。
注意:根据您的数据库,删除可能是一个非常快速的操作,或非常慢。最终,删除行涉及将行标记为未使用,然后将该行占用的空间返回到表中,以便可以插入新行。变长行(由于可变长度数据类型)和内部实现细节使这变得复杂。例如,PostgresQL仅将行标记为已删除,然后使用单独的手动调用进程(vacuum)将已删除行使用的空间返回到表以用于新行。我相信PostegresQL仍将行更新视为删除,然后是插入。 MySQL和Oracle以及SQL Server都有不同的方法来实现相同的最终结果,每种方法都会对系统性能产生更复杂的副作用。
您需要学习您的文档和任何性能指南,以确定哪种方式最适合您的系统。
答案 1 :(得分:1)
我在mySQL方面没有经验,但在其他DBMS上我处理过更新,然后删除不帮助。只需尝试大量数据并测量删除与更新+删除的时间。如果作为“坏”标准的列具有索引,则会有所帮助。
答案 2 :(得分:0)
如果您考虑将行更新为错误,然后将其删除,则会给服务器带来额外的压力。
直接删除它们是更好的选择。
如果您认为会有大量不良行,请以一种不会一次删除超过100行的方式创建一个cron。这应该会在一定程度上限制服务器负载。