创建具有基于其他表列值生成的布尔列的表?

时间:2019-04-29 19:39:36

标签: sql postgresql

我有表A,B,C,每个表都有数百万行。表B和C引用表A。这些表主要用于具有多个过滤器的一个查询,但是这些过滤器中只有一个在查询之间有所不同。由于常量参数会增加查询执行时间,因此我想知道是否存在一种将这些参数预先计算到新表中的方法。我当时在查看物化视图,但问题是我想要的计算类型将与原始列类型不同。为了解释,我将举一个例子。

说这些表代表一个书店数据库。表A包含常规信息,表B包含每本书的多个代码,以指示它们属于哪些类别,例如406, 678, 252..。我正在建立一个查询来搜索仅属于这些类别中的3类的图书。这里的变量是书中的关键词搜索。我将始终需要这3类(代码)下的书籍,因此它们是常量。

我想做的是创建一个表,在该表中将有一列,告诉我给定的序列是否属于这3个代码之下。这可以通过布尔类型来完成。我不想为每个查询而联接这些表并为这3个代码(在实际场景中更多)进行过滤。.据我了解,物化视图无法生成字段?

您认为这里有什么好的解决方案?

1 个答案:

答案 0 :(得分:1)

您有多种选择。

部分索引

PostgreSQL允许您使用where子句创建索引,如下所示:

create index tableb_category on tableb (category)
where category in (406, 678, 252);

为这些类别创建视图:

create view v_books_of_interest
as
select tablea.*, tableb.*
from tablea
inner join table b
   on tableb.bookid = tablea.bookid
   and tableb.category in (406, 678, 252);

现在,您的查询可以使用book_of_interest而不是book。坦白说,我首先开始。具有正确索引的查询优化有很长的路要走。多个表中的数百万行是可管理的。

材料化视图

create materialized view mv_books_of_interest
as
select tablea.*, tableb.*
from tablea
inner join table b
   on tableb.bookid = tablea.bookid
   and tableb.category in (406, 678, 252);
with no data;

定期运行cron作业(或类似方法)以刷新它:

refresh materialized view mv_books_of_interest;

分区数据

https://www.postgresql.org/docs/9.3/ddl-partitioning.html将帮助您入门。如果您的团队支持表继承,那就太好了。试一试,看看它如何适合您的用例。

触发

在tableA(或tableB,取决于您如何访问数据)中创建一个is_interesting字段。创建一个触发器,该触发器在将数据插入依赖项时检查特定条件,然后将书的标记设置为true / false。这样可以使查询运行得更快,但可能会降低插入和更新的速度。