我有两张桌子,让我们说
NoReverseMatch: Reverse for 'websitedetail' with arguments '()' and keyword arguments '{'pk': 42, 'slug': u'when-you-talk-you-hardly-even-look-in-my-eyes'}' not found. 1 pattern(s) tried: ['dashboard/(?P<slug>[-\\w]+])-by-(?P<pk>\\d+)/$']
我是以下列方式加入他们的:
CREATE TABLE a (
a_a BIGINT,
a_b BIGINT,
a_c BIGINT,
a_someval NUMERIC
);
CREATE TABLE b (
b_a BIGINT,
b_b BIGINT,
b_c BIGINT,
b_someval NUMERIC
);
解释显示,该计划程序需要对JOIN中使用的列进行排序。
有没有办法对这些表进行预先排序,以便每次加入时都不会对它们进行排序?
一些可能很重要的事情:
答案 0 :(得分:0)
如果您确实希望确保表格基本上在join
之前编辑和排序,则可以创建join
个join
个表格。
这将导致物化视图已将两个表的结果CREATE MATERIALIZED VIEW ab_mat AS
SELECT *
FROM a
JOIN b ON (a.a_a = b.b_a AND a.a_b = b.b_b AND a.a_c = b.b_c);
编辑在一起并按您选择的顺序排序。您还可以在任何字段上创建索引,这与常规视图不同。
代码将类似于:
REFRESH MATERIALIZED VIEW
这种方法的一个潜在缺点是物化视图无法更新,因此信息不是实时的(这就是为什么它们提供了更好的性能 - 它们本质上是持久化的视图快照到磁盘)。但是,对于许多用例来说,这是完全正常的。
要更新信息,只需创建一个 cron作业,在您需要的时间间隔内定期在物化视图上运行SELECT *
FROM ab_mat
-- optional ordering
order by a, b, c;
命令。这可以从相对激进(例如每5分钟)到相对宽松(例如每5分钟),例如相对宽松。每天或每周。
请注意,物化视图可以依次连接到其他表和视图,以混合实时信息。我最近使用了这样的混合设置来极大地提高极其复杂的查询的速度,其中只有一些数据需要真正实时。
另请注意,物化视图在9.3之前的版本中不可用。
根据OP的评论进行编辑:
您可以选择在视图中指定顺序,在这种情况下,它将默认为该顺序,或者您可以将其保持无序,如上所述,并且每次都动态订购。
您可以像这样查询物化视图:
join
这意味着它根本不需要做任何return randomNumber;
,因为它已经完成并保存了。
答案 1 :(得分:0)
我很惊讶这需要排序,但如果是这样,那么诀窍是获得一个大的工作内存区域。我本来希望哈希加入是诚实的。
您可以考虑是否可以实现两个表的分区,两个源表在同一个键定义上进行分区。我不确定PostgreSQL是否与Oracle类似地实现了分区智能连接,但如果没有,那么您可以使用以下查询手动实现它:
SELECT *
FROM a_part01
JOIN b_part01 ON (a.a_a = b.b_a AND a.a_b = b.b_b AND a.a_c = b.b_c)
union all
SELECT *
FROM a_part02
JOIN b_part02 ON (a.a_a = b.b_a AND a.a_b = b.b_b AND a.a_c = b.b_c)
union all
...
union all
SELECT *
FROM a_part0n
JOIN b_part0n ON (a.a_a = b.b_a AND a.a_b = b.b_b AND a.a_c = b.b_c);
...或作为一系列单独的查询:
CREATE TABLE result
AS
SELECT *
FROM a_part01
JOIN b_part01 ON (a.a_a = b.b_a AND a.a_b = b.b_b AND a.a_c = b.b_c);
...
INSERT INTO result
SELECT *
FROM a_part0n
JOIN b_part0n ON (a.a_a = b.b_a AND a.a_b = b.b_b AND a.a_c = b.b_c)
这允许以更低的内存占用完成查询。
关于预先分配表数据,我不确定PostgreSQL是否在插件或表创建时尊重ORDER BY,但您可以轻松地测试它以查找。如果是这样,您可以对表进行排序,但数据库不会知道它们已排序。但是,实际意义可能只是连接更有效,因为对已经排序的数据进行排序可能更有效。我会说它绝对值得测试。
但是,您仍然在实施一种数据,只是在整个操作的不同部分。
如果索引覆盖了表的所有列,那么实际使用索引可能会有所帮助。虽然创建索引需要排序,所以你只是在其他地方做工作。