Postgresql在一列或大表中获取唯一值集的最快方法

时间:2013-11-17 22:03:11

标签: sql database postgresql set unique

我在Postgresql数据库中有一个不断增长的,可能非常大的表,其中包含来自不同“通道”的“数据”,用于不同的“设备”,例如:

Table data:
  id (PK)
  device_id (FK -> device)
  channel_id (FK -> channel)
  timestamp (TIMESTAMP)
  value (Float)

我正在使用分区将表分成多个子表,每个设备一个,因为我从不需要同一查询中不同设备的数据。由于并非所有设备都提供所有通道,因此我想获得单个设备的所有可用通道的列表。一个简单的SQL查询解决了我的问题:

SELECT DISTINCT(channel_id) FROM data where device_id = 1;

这很好用,但对于数据表中包含许多条目的设备需要很长时间。使用分区加快了这个过程,因为数据库只需要遍历一个设备的条目,但是对于某些设备来说仍需要很长时间才能完成。

我的应用程序的属性很少发生为一个设备添加新的通道类型。在将设备添加到数据库之后,通常会快速添加通道,之后不会添加任何新通道。但是,频繁添加可用频道的数据。我还需要经常向用户显示每个设备的可用频道列表,因此希望加速查找可用频道。我已经有了一个关于channel_ids的索引,希望它能加快获得所需的列表,但是它仍然需要很长时间来检索列表。

目前,我可以想出几种方法来解决我的问题:

  1. 使用postgres的一些“魔法”功能,它完全符合我的要求但我对此一无所知。
  2. 使用触发器维护某些类别的额外表格,每个“设备”/“频道”组合只包含一个条目,因此可以快速访问可用的频道。但是,由于经常插入新数据,我认为触发器会产生相当多的开销,而在极少数情况下它只能检测到新的通道。
  3. 重新考虑我的数据库设计。也许插入另一个包含“channel”和“device”之间链接的表,然后在该表的“data”中只有一个FK。中间表上的查询应该很快,但是,这基本上会增加我将数据插入数据库的应用程序的复杂性。
  4. 也许视图在这里有帮助吗?
  5. 在我的前端使用缓冲只定期执行查询,因为可用的频道不会经常更改。
  6. 点2和3.在我看来,他们会增加很多不必要的开销,我想避免。由于我没有找到关于这个主题的任何内容,我现在认为解决方案5.是我的方式。但是,我想知道是否有人为我的问题找到了更好的,可能基于数据库的解决方案。

    感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

对于选项1,您要做的是“松散索引扫描”或“跳过扫描”。

如果PostgreSQL在有利的情况下自动执行这些操作会很好,但截至目前它并没有这样做。但你可以trick it into it.我从来没有在分区表上尝试过这个,但我认为将合适的WHERE子句添加到union的每个分支都很简单。

也许您也想要选项3,或者相反,我没有足够的信息可以说。