【发布时间】:2021-07-10 16:13:22
【问题描述】:
谁能解释一下 Postgres 何时/如何处理针对视图的搜索?我对查询视图而不是表有偏见,这绝对是错误的。我不确定我的偏见是完全还是部分不合理。
潜伏在我脑海中的想法是,在某些情况下,视图缺乏来自查询的过滤条件,会生成一个大型产品,然后根据查询条件选择该产品。之后。 (我想我在 5.6 年前在 MySQL 中遇到过这样的情况,其中 MySQL 生成了一个 CROSS JOIN 来执行一些外部连接。即使结果中有两条记录可预测,它也需要几分钟才能运行。MySQL 不是 Postgres。)
我有一个使用INNER JOIN 将两个表的结果组合在一起的视图。目前,总产品约为 1.52 亿行。 Count(*) 运行需要一些时间,正如您所想象的那样。
我创建了两个存储函数来比较性能。他们都使用rcl_combined 作为RETURN 格式。
-
rcl_combined_query执行与rcl_combined视图相同的select,但包含针对索引字段的where条件。 -
rcl_combined_query_on_view直接搜索视图。
我在下面列出了代码。当我尝试这个时,函数执行相同的方式,并为“function_scan”生成相同的简单计划。毫秒结果,无论哪种方式。
我的偏见完全没有根据吗?或者是否存在直接查询表而不是查询 Postgres 13+ 中的视图更安全的情况(或边缘情况)?希望这不是一个不可能的问题。我们正在使用FROM、(INNER) JOIN、LEFT JOIN,有时还使用RIGHT JOIN,它们几乎只用于小表、小表和稍大的表,但仍处于 200M 以下的行范围内。
我明白这可能是一种“视情况而定”的情况,我希望至少能澄清我在这里的一些错误假设。我不希望任何人给出确切的公式等。
-----------------------------------------------------------------
-- The view used as a result format by both of the functions, and
-- as the search target for the second query.
-----------------------------------------------------------------
CREATE OR REPLACE VIEW api.rcl_combined AS
SELECT
record_changes_log.id,
record_changes_log.record_id,
record_changes_log.table_number,
record_changes_log.updated_dts,
record_changes_log.updated_by,
record_changes_log.app_type,
record_changes_log.machine_name,
record_changes_log_detail.id AS details_id,
record_changes_log_detail.field_name,
record_changes_log_detail.old_value,
record_changes_log_detail.new_value
FROM (record_changes_log
JOIN record_changes_log_detail ON ((record_changes_log.id = record_changes_log_detail.record_changes_log_id)));
-----------------------------------------------------------------
-- A function that returns the same data as the pet_pretty view
-- using the rcl_combined view format/type.
-----------------------------------------------------------------
CREATE OR REPLACE FUNCTION rcl_combined_query (record_id_in uuid)
RETURNS rcl_combined -- Used for the format definition and dependency tracking.
LANGUAGE sql STABLE
AS
$BODY$
-- The select, from and join recapitulate what's in the view.
SELECT
record_changes_log.id,
record_changes_log.record_id,
record_changes_log.table_number,
record_changes_log.updated_dts,
record_changes_log.updated_by,
record_changes_log.app_type,
record_changes_log.machine_name,
record_changes_log_detail.id AS details_id,
record_changes_log_detail.field_name,
record_changes_log_detail.old_value,
record_changes_log_detail.new_value
FROM record_changes_log
JOIN record_changes_log_detail
ON record_changes_log.id = record_changes_log_detail.record_changes_log_id
WHERE record_changes_log.record_id = record_id_in;
$BODY$;
-----------------------------------------------------------------
-- A function that returns the same data as the pet_pretty view
-- by searching on it.
-----------------------------------------------------------------
-- Just being thorough here, I'm very unlikely to write a function to query a view.
CREATE OR REPLACE FUNCTION rcl_combined_query_on_view (record_id_in uuid)
RETURNS rcl_combined -- Used for the format definition and dependency tracking.
LANGUAGE sql STABLE
AS
$BODY$
SELECT * from rcl_combined where record_id = record_id_in;
$BODY$;
【问题讨论】:
标签: postgresql optimization view