数据库性能:对列与单独表进行过滤

时间:2010-10-27 10:14:31

标签: database performance database-design postgresql

我想知道以下情况的最佳方法是什么:

我在数据库中有一个显然包含所有订单的Orders表。但这些都是字面上的所有订单,因此包括刚刚标记为“完整”的完整/已完成订单。从所有未结订单我想要计算一些东西(如开放金额,未清项目等)。什么会更好的表现明智:

将1个订单表保留所有订单,包括完整/存档订单,并通过过滤“完整”标记进行计算?

或者我应该创建另一个表格,例如'Orders_Archive',以便Orders表只包含我用于计算的未结订单?

这些方法中是否有(明显的)性能差异?

(B.T.W。我正在使用PostgreSQL数据库。)

4 个答案:

答案 0 :(得分:7)

这是数据库设计中的常见问题:是否要分离或“归档”不再“活动”的记录的问题。

最常见的方法是:

  • 一张表中的所有内容,将订单标记为“完整”。优点:最简单的解决方案(代码和结构方面),良好的灵活性(例如易于“复活”的订单)。缺点:表格可能会变得非常大,这对于查询和例如查询都是一个问题。备份。
  • 将旧内容存档到单独的表中。从第一种方法解决问题,代价是更复杂。
  • 使用表格进行基于值的分区。这意味着逻辑上(对应用程序)一切都在一个表中,但在幕后,DBMS根据某些列上的值将内容放入不同的区域。您可能使用“完整”列或分区的“订单完成日期”。

最后一种方法结合了前两种方法的优点,但需要DBMS支持,设置起来比较复杂。

注意:

仅存储“存档”数据的表通常称为“存档表”。有些DBMS甚至为这些表(例如MySQL)提供了特殊的存储引擎,这些表经过优化,可以快速检索和提高存储效率,但代价是缓慢的更改/插入。

答案 1 :(得分:6)

  

或者我应该创建另一个表格,例如'Orders_Archive',以便Orders表只包含我用于计算的未结订单?

是。他们称之为数据仓库。人们这样做是因为它加速了交易系统,以消除几乎没有用过的历史。首先,表格在物理上更小,处理速度更快。其次,长期运行的历史报告不会干扰事务处理。

  

这些方法中是否有(明显的)性能差异?

是。奖金。您可以重新构建历史记录,使其不再是3NF(用于更新),而是用于星型模式(用于报告)。优点是巨大的。

购买Kimball的数据仓库工具包一书,了解有关星型模式设计的更多信息,并将历史记录从活动表迁移到仓库表中。

答案 2 :(得分:4)

从不拆分或分离当前/存档数据。这完全是不正确的。它可能被称为“数据仓库”或一桶鱼,但它是错误的,不必要的,并且创建其他方面没有的问题。结果是:

  • 现在,每个查询数据的人都必须在两个地方而不是一个
  • 中查找
  • 更糟糕的是,手动(在Excel或其他任何方面)添加聚合值
  • 你在密钥中引入异常,完整性丢失(否则单个数据库约束将是唯一的)
  • 当需要更改已完成订单(或多个)时,您必须将其从“仓库”中取出并将其放回“数据库”

如果且仅当表上的响应很慢时,则解决该问题,并提高速度。只要。没有其他的。这(在我看到的每种情况下)都是索引错误(缺少索引或不正确的列或不正确的列序列都是错误)。通常,您需要的只是索引中的IsComplete列,以及您的用户用于搜索最频繁的任何内容,进入/排除开放/完成订单。

现在,如果您的dbms平台无法处理大型表或大型结果集,那么这是一个不同的问题,您必须使用该工具中可用的任何方法。但作为一个数据库设计问题,这是完全错误的;除非您受到平台的限制,否则无需创建副本,填充和维护副本(包含所有后续问题)。

去年和今年,作为普通性能分配的一部分,我已经整合了数十亿行的拆分表(并且必须解决所谓的“不存在”的所有重复行问题,是的,2天只是为了那个)。具有更正指数的合并表比拆分表更快; “数十亿行放慢桌面速度”的借口完全是错误的。用户爱我,因为他们不再需要使用两个工具并查询两个“数据库”来获得他们需要的东西。

答案 3 :(得分:1)

由于您使用的是postgresql,因此您可以利用部分索引。假设对于未完成的订单,您经常使用 orderdate ,您可以像这样指定索引:

create index order_orderdate_unfinished_ix on orders ( orderdate )
  where completed is null or completed = 'f';

当您放置该条件时,postgresql将不会索引已完成的订单,从而节省了硬盘空间并使索引更快,因为它只包含少量数据。因此,您可以在没有桌子分离麻烦的情况下获得好处。

将数据分成ORDERS和ORDERS_ARCHIVE时,您必须调整现有报告。如果您有很多报告,那可能会很痛苦。

请参阅此页面中部分索引的完整说明:http://www.postgresql.org/docs/9.0/static/indexes-partial.html

编辑:对于存档,我更喜欢创建具有相同模式的另一个数据库,然后将旧数据从事务数据库移动到此存档数据库。