postgres 如何处理对某些列具有假值的视图的查询?
Posted
技术标签:
【中文标题】postgres 如何处理对某些列具有假值的视图的查询?【英文标题】:How postgres process a query on a view with fake values for some columns? 【发布时间】:2019-07-25 09:04:45 【问题描述】:3 个表格和 1 个视图 查询将如何使用假的“null as col”值?
Table1
- IndexedCol1
- Col2
- CommonIndexedCol1
- CommonIndexedCol2
- CommonIndexedCol3
Table2
- IndexedCol2
- Col3
- Col4
- CommonIndexedCol1
- CommonIndexedCol2
- CommonIndexedCol3
Table3
- IndexedCol3
- Col5
- Col6
- CommonIndexedCol1
- CommonIndexedCol2
- CommonIndexedCol3
View1
- Table1.IndexedCol1
- Table2.IndexedCol2
- Table3.IndexedCol3
- CommonIndexedCol1
- CommonIndexedCol2
- CommonIndexedCol3
View1 查询是:
SELECT IndexedCol1, null as IndexedCol2, null as IndexedCol3, CommonIndexedCol1, CommonIndexedCol2, CommonIndexedCol3 FROM Table1
UNION
SELECT null as IndexedCol1, IndexedCol2, null as IndexedCol3, CommonIndexedCol1, CommonIndexedCol2, CommonIndexedCol3 FROM Table2
UNION
SELECT null as IndexedCol1, null as IndexedCol2, IndexedCol3, CommonIndexedCol1, CommonIndexedCol2, CommonIndexedCol3 FROM Table3
假设每个表有 100 万行
如果我运行以下查询
SELECT * FROM View1 WHERE CommonIndexedCol1=1 AND IndexedCol1 is NOT NULL
postgres 是否会跳过具有 SELECT(null as IndexedCol1)的选择,因此仅查询 1 个表,仅 100 万行,它是否理解此选择将导致所有空值,因此它应该跳过第二个和第三个选择查询开始? 或者它会查询 3 个表中的全部 300 万条记录是否为非空 IndexedCol1?
【问题讨论】:
PostgreSQL 支持EXPLAIN 告诉你它将如何处理查询.. 运行explain (analyze) select ...
,你会看到Postgres会做什么
@a_horse_with_no_name 是的,问题中的拼写错误,已修复...我现在就写EXPLAIN
,谢谢
【参考方案1】:
postgres 如何处理对某些列的假值视图的查询?
PostgreSQL 优化器应该将 WHERE 子句从在 VIEW 上进行的查询下推到 VIEW 查询定义。
换句话说,PostgreSQL 上的 VIEW 处理/处理优化就像 SQL“预处理器”或模板系统一样工作。
查询
SELECT *
FROM View1
WHERE CommonIndexedCol1 = 1 AND IndexedCol1 is NOT NULL
会改写成
SELECT *
FROM
(SELECT
IndexedCol1
, null as IndexedCol2
, null as IndexedCol3
, CommonIndexedCol1
, CommonIndexedCol2
, CommonIndexedCol3
FROM
Table1
WHERE
CommonIndexedCol1 = 1 AND IndexedCol1 IS NOT NULL
UNION
SELECT
null as IndexedCol1
, IndexedCol2
, null as IndexedCol3
, CommonIndexedCol1, CommonIndexedCol2, CommonIndexedCol3
FROM Table2
WHERE CommonIndexedCol1=1 AND IndexedCol1 is NOT NULL
UNION
SELECT
null as IndexedCol1
, null as IndexedCol2
, IndexedCol3
, CommonIndexedCol1
, CommonIndexedCol2
, CommonIndexedCol3
FROM Table3
WHERE CommonIndexedCol1=1 AND IndexedCol1 is NOT NULL
) AS View1
经过更多优化(扁平化)
SELECT
IndexedCol1
, null as IndexedCol2
, null as IndexedCol3
, CommonIndexedCol1
, CommonIndexedCol2
, CommonIndexedCol3
FROM Table1
WHERE CommonIndexedCol1=1 AND IndexedCol1 is NOT NULL
UNION
SELECT
null as IndexedCol1
, IndexedCol2
, null as IndexedCol3
, CommonIndexedCol1, CommonIndexedCol2, CommonIndexedCol3
FROM Table2
WHERE CommonIndexedCol1=1 AND IndexedCol1 is NOT NULL
UNION
SELECT
null as IndexedCol1
, null as IndexedCol2
, IndexedCol3
, CommonIndexedCol1
, CommonIndexedCol2
, CommonIndexedCol3
FROM Table3
WHERE CommonIndexedCol1=1 AND IndexedCol1 is NOT NULL
如果你想跑
EXPLAIN SELECT * FROM View1 WHERE CommonIndexedCol1=1 AND IndexedCol1 is NOT NULL
您应该看到 Table1、Table2 和 Table3,并且在说明中没有提到 View1..
【讨论】:
以上是关于postgres 如何处理对某些列具有假值的视图的查询?的主要内容,如果未能解决你的问题,请参考以下文章