Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.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 查询优化器是否能够从WHERE子句中提取有效常量以避免重复计算?_Sql_Postgresql_Query Optimization - Fatal编程技术网

Sql 查询优化器是否能够从WHERE子句中提取有效常量以避免重复计算?

Sql 查询优化器是否能够从WHERE子句中提取有效常量以避免重复计算?,sql,postgresql,query-optimization,Sql,Postgresql,Query Optimization,重写一个如下所示的函数是否会带来性能方面的好处: CREATE FUNCTION some_text_predicate(name text) RETURNS boolean AS $$ SELECT EXISTS (SELECT 1 FROM sc.foo WHERE foo.name = some_transform(name) ); $$ LANGUAGE SQL; 因此: CREATE FUNCTION some_text_predicate(text)

重写一个如下所示的函数是否会带来性能方面的好处:

CREATE FUNCTION some_text_predicate(name text) RETURNS boolean AS $$
    SELECT EXISTS (SELECT 1 FROM sc.foo
        WHERE foo.name = some_transform(name)
    );
$$ LANGUAGE SQL;
因此:

CREATE FUNCTION some_text_predicate(text) RETURNS boolean AS $$
    DECLARE
        name text := some_transform($1);
    BEGIN
        RETURN EXISTS (SELECT 1 FROM sc.foo
            WHERE foo.name = name
        );
    END;
$$ LANGUAGE plpgsql;
基本原理是,
some_transform
的结果是一个常量,不需要在执行
WHERE
子句的每一行上重新计算。查询优化器是否足够聪明,可以将其提取为常量,或者我必须使用第二个函数定义才能获得我想要的好处


我正在寻找优化
WHERE
子句求值的详细信息。

这一切都取决于
查询的某些转换

如果该函数是
不可变的
(保证对相同的参数返回相同的结果)或
稳定的
(在当前查询期间对相同的参数返回相同的结果,并且不修改数据库),则可以将函数标记为相同的

然后优化器将知道,如果参数在查询期间保持不变,则只需对函数求值一次

在计划查询时,将对
不可变的
函数进行评估,在执行时对
稳定的
函数进行评估

这将有助于您处理以下查询:

WHERE a.x = some_text_predicate('const')
但不是用

WHERE some_text_predicate(a.x) = 'const'
如果你能从中获益,我更喜欢第一个函数,因为它更简单


如果无法避免经常调用该函数,那么第二个函数可能更好,因为PL/pgSQL函数缓存执行计划。但是您无法避免这样多次调用昂贵的函数。

如果您将
某些转换
标记为
稳定
不可变
,以更合适的为准,它只会被计算一次。如果SQL函数被声明为
稳定的
不可变的
,那么它不也是比PL/pgSQL开销更有效的内联的候选者吗?如果它包含子查询,则不会。即使某些转换是不可变的,我无法将某些\u text\u谓词标记为不可变,因为它的结果取决于sc.foo的内容,对吗?对,它将是
稳定的