【问题标题】:Moving records to another table vs. "flag" column SQL performance将记录移动到另一个表与“标志”列 SQL 性能
【发布时间】:2015-02-26 21:33:16
【问题描述】:

假设我有一个代表“任务队列”(数千万条记录)的表。

任务可以“排队”或“完成”。

如果我们要抓取 10 个任务来处理,哪个性能更好?

  • 带有“标志”列的单个表,例如 ENUM / BIT / TINYINT 将任务标记为已完成或未完成(最终在列上建立索引)
  • 为排队的任务和已完成的任务分开表,并将每个已完成的任务从排队插入到已完成删除

请注意,在开始时,我们有几个或没有完成的任务,但随着处理的进行,将会有数百万个已经完成的任务。

【问题讨论】:

  • 你可以指定dbms。
  • @jarlh 目前是 aboyt MySQL,但也在 Oracle 上下文中询问,因此未指定。

标签: sql database performance indexing schema


【解决方案1】:

可能没关系,但如果是我,我会使用一张桌子。这是我的推理:

首先,我们必须假设此表上有良好的索引,这将使查找速度更快。有了适当的索引,如果你想查询排队的任务,不管“完成”任务的数量是 10 还是 100 亿,DBMS 只会查看排队的任务。

其次,随着任务从“排队”变为“完成”,您将更新其状态。这需要 DBMS 对索引进行一些重组,但这没关系,他们已经高效率地这样做了 30 年了。

如果您要将它们拆分到单独的表中,基本上将记录从一个地方移动到另一个地方的维护工作将放在您的代码中,而不是放在 DBMS 索引重组代码中。哪些代码库经过更好的测试和更高的性能? :)

最后一个论点 - 如果您将所有内容放在一张大表中,则对这些任务管理的进一步性能调整将成为 DBMS 配置问题,而不是软件开发问题。这是我书中的一大胜利。您可以通过各种疯狂的配置来提高任何 DBMS 的性能,包括垂直和水平分区等。如果您分发数据的方式是通过嵌入在您的软件中的某种方案,那么这些东西将不是选项。

所以底线 - 如果您使用 2 表方法,我认为它的执行方式与您使用单表方法非常相似,一旦您考虑到您的代码必须做的额外工作来移动记录.如果您从一个表中删除“打开”任务并将其粘贴到“完成”表中,请记住 DBMS 仍然必须更新源表上的“打开”索引。因为可能不会有很大的性能差异,所以您应该使用单表方法,因为它对您来说工作量更少,并且在以后为您提供更大的灵活性(通过配置提高速度,副软件)

【讨论】:

  • 另外,我已经完成了大约 200 万个具有“排队/完成”状态的容量测试,并且使用索引选择 100 个任务非常快,甚至比按状态分区还要快跨度>
  • 我在使用 RDBMS 软件多年后学到的一件事 - 如果 RDBMS 软件提供了做某事的功能,那么通常您应该使用它而不是自己动手。说真的,自 60 年代以来,他们一直在对这些事情进行研究和查询优化,除非您的要求非常奇怪或定制,否则您几乎不可能在性能方面做得更好。您可以期望的最好结果是重新实现他们所做的,并且在性能方面获得相同的结果,而不是更好。
  • @FrobberOfBits - 问题发布已经有一段时间了,但假设您在查询某些内容时在表中使用了几个标志字段(即 IsAvailable 和 IsDeleted),我需要始终确保IsAvailable = 'true' 和 IsDeleted = 'false'。这不会比查询仅包含可用记录和未删除记录的表慢,而是在记录等待“可用”时使用单独的表,而另一个表用于删除但需要的记录保留用于存档目的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多