Zil*_*ilk 7 postgresql performance view union postgresql-performance
(编辑:请参阅结尾以获得更简单的示例)
我在一个名为“cases”(135k 行,29 列)的表中搜索。此表中的某些行具有父子关系类型(不同类型),这意味着对于这些记录,必须混合使用父/子字段来过滤和显示。
我已经确定了四种不同的父子关系并为它们创建了视图:
这些视图的结果不重叠,共同覆盖了表格的 100%。
当我选择所有这些的联合并分别过滤每个视图时,查询需要大约 9 毫秒。选择所有视图的联合并过滤其结果大约需要 500 毫秒。
我还在没有视图的情况下对此进行了测试,内联了它们包含的查询,但没有产生可衡量的改进。
这是快速查询(解释):
SELECT c.*
FROM caselist_no_specials c
JOIN case_clients cacl ON cacl.case_id = c.main_id
WHERE cacl.client_id = 12046
UNION ALL
SELECT c.*
FROM caselist_disputes_with_ipr c
JOIN case_clients cacl ON cacl.case_id = c.main_id
WHERE cacl.client_id = 12046
UNION ALL
SELECT c.*
FROM caselist_mark_children c
JOIN case_clients cacl ON cacl.case_id = c.main_id
WHERE cacl.client_id = 12046
UNION ALL
SELECT c.*
FROM caselist_design_children c
JOIN case_clients cacl ON cacl.case_id = c.main_id
WHERE cacl.client_id = 12046
ORDER BY sort_nr,
id;
Run Code Online (Sandbox Code Playgroud)
如您所见,每个视图的连接和过滤器都是重复的。试图避免重复产生了这个查询,这需要更长的时间(解释):
SELECT x.*
FROM (
SELECT * FROM caselist_no_specials
UNION ALL
SELECT * FROM caselist_disputes_with_ipr
UNION ALL
SELECT * FROM caselist_mark_children
UNION ALL
SELECT * FROM caselist_design_children
) x
JOIN case_clients cacl ON cacl.case_id = x.main_id
WHERE cacl.client_id = 12046
ORDER BY x.sort_nr,
x.id;
Run Code Online (Sandbox Code Playgroud)
是否有可能以某种方式让 PostgreSQL 知道外部查询上的过滤器/连接可以应用于内部子查询?
或者有没有其他方法可以避免单独过滤每个视图?此查询的面向用户的表单有 20 多个过滤器字段,并且可以有多达 14 个附加表的 JOIN。
PostgreSQL 是在 Linux 上运行的 9.4.7 版。
编辑:我创建了一个非常简单的示例,简单地使用 3 个视图对原始表进行分区,但不涉及其他表(以及两种变体的查询计划)。回想起来,这是我首先应该用作示例的。
小智 5
您要求数据库在查询一中执行的操作是: 给我表 A 中的所有已过滤的 给我表 B 中的所有已过滤的 给我表 C 中的所有已过滤的 给我来自表 D 中的所有已过滤的 然后联合。
在第二个查询中,您首先获取所有数据,然后才进行连接和过滤。UNION 查询上的 JOIN 和 WHERE 并不能真正让您对任何内容建立索引,显然运行速度较慢。(它与服务器变体或操作系统无关)。
归档时间: |
|
查看次数: |
3712 次 |
最近记录: |