Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 过滤集返回函数结果_Sql_Postgresql - Fatal编程技术网

Sql 过滤集返回函数结果

Sql 过滤集返回函数结果,sql,postgresql,Sql,Postgresql,我希望澄清我对集返回函数在PostgreSQL中的幕后行为的理解 让我们设置一个名为“a_at_date”的集合返回函数,该函数返回: SELECT * FROM a WHERE date = a_date 其中,_日期是一个函数参数 如果我这样使用: SELECT * FROM a_at_date(a_date) WHERE other_field = 123 那么,例如,这是否可以利用[date,other_field]上的索引,就像它可以: SELECT * FROM a WHER

我希望澄清我对集返回函数在PostgreSQL中的幕后行为的理解

让我们设置一个名为“a_at_date”的集合返回函数,该函数返回:

 SELECT * FROM a WHERE date = a_date
其中,_日期是一个函数参数

如果我这样使用:

SELECT *
FROM a_at_date(a_date) 
WHERE other_field = 123
那么,例如,这是否可以利用[date,other_field]上的索引,就像它可以:

SELECT *
FROM a
WHERE a = a_date AND other_field = 123

换句话说,集合返回函数是否独立于任何外部查询运行,从而限制了索引选项?

原则上,优化器不知道函数做什么–函数体是由函数过程语言的调用处理程序处理的字符串

一个例外是用sql语言编写的函数。如果它们足够简单,并且可以证明内联它们不会改变SQL语句的语义,那么查询重写器将内联它们

请参见
backend/optimizer/prep/prepjointree.c
中的以下注释:

/*
*内联设置返回函数
*尝试在FROM子句中“内联”设置返回函数。
*
*如果RTE_函数rtable entry调用集合返回函数
*只包含一个简单的选择,我们可以将rtable条目转换为
*RTE_子查询条目直接公开SELECT。这尤其重要
*如果子查询可以被“拉起”以进行进一步优化,那么它将非常有用,
*但我们即使不这样做,也是为了减少执行器开销。
*
*这必须在我们开始对其进行任何优化之前完成
*子查询,否则任何此类步骤都不会应用于子查询
*通过内联获得。但是,我们在拉上子链接后执行此操作
*这样我们就可以内联子链接子选择中使用的任何函数。
*
*与大多数planner一样,它可以随意在输入数据上涂鸦
*结构。
*/
backend/optimizer/util/clauses.c
中的
inline\u set\u returning\u函数
中还有两条有指导意义的注释:

/*
*如果函数不是SQL语言或有其他限制,请忘记它
*财产。特别是,它不能被宣布为严格的,因为我们
*不能强制执行。它也不能是易变的,因为这是
*应该让它使用自己的快照执行,而不是
*共享调用查询的快照。(重新检查程序设置为
*只是偏执狂。)
*/

/*
*确保函数(仍然)返回它声明的内容。这
*如果出错,将引发错误,但这没关系,因为函数将
*无论如何,在运行时都会失败。请注意,check_sql_fn_retval也将插入
*如果需要创建tlist,则重新标记类型和/或空列
*表达式与声明的函数类型匹配。
*
*如果函数返回复合类型,除非检查
*显示它返回一个完整的元组结果;否则它是什么
*返回的是一个组合列,这不是我们需要的。(如
*检查_sql_fn_retval,我们故意排除复合上的域
*在这里。)
*/
使用
EXPLAIN
查看函数是否内联

其工作原理的一个示例:

CREATE TABLE a (
   "date" date NOT NULL,
   other_field text NOT NULL
);

CREATE OR REPLACE FUNCTION a_at_date(date)
   RETURNS TABLE ("date" date, other_field text)
   LANGUAGE sql STABLE CALLED ON NULL INPUT
   AS 'SELECT "date", other_field FROM a WHERE "date" = $1';

EXPLAIN (VERBOSE, COSTS off)
SELECT *
FROM a_at_date(current_date)
WHERE other_field = 'value';

                               QUERY PLAN                                
-------------------------------------------------------------------------
 Seq Scan on laurenz.a
   Output: a.date, a.other_field
   Filter: ((a.other_field = 'value'::text) AND (a.date = CURRENT_DATE))
(3 rows)

你可以看看执行计划。由于不太了解Postgres优化,我认为集合返回函数在优化方面是一个“障碍”。也就是说,如果出于优化目的将外部谓词传递到函数中,我会感到惊讶