我有表A,B,C,每个表都有数百万行。表B和C引用表A。这些表主要用于具有多个过滤器的一个查询,但是这些过滤器中只有一个在查询之间有所不同。由于常量参数会增加查询执行时间,因此我想知道是否存在一种将这些参数预先计算到新表中的方法。我当时在查看物化视图,但问题是我想要的计算类型将与原始列类型不同。为了解释,我将举一个例子。
让说这些表代表一个书店数据库。表A包含常规信息,表B包含每本书的多个代码,以指示它们属于哪些类别,例如406, 678, 252..
。我正在建立一个查询来搜索仅属于这些类别中的3类的图书。这里的变量是书中的关键词搜索。我将始终需要这3类(代码)下的书籍,因此它们是常量。
我想做的是创建一个表,在该表中将有一列,告诉我给定的序列是否属于这3个代码之下。这可以通过布尔类型来完成。我不想为每个查询而联接这些表并为这3个代码(在实际场景中更多)进行过滤。.据我了解,物化视图无法生成字段?
您认为这里有什么好的解决方案?
答案 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。这样可以使查询运行得更快,但可能会降低插入和更新的速度。