使用SQL函数而不是SELECT函数的优点
在Postgresql 9.0数据库中,我可以使用WHERE子句中的整数(profile_id)为带有SELECT语句的网页创建url 在过去,我只是在方便的时候进行选择,例如在视图中将子查询用作列/字段。但是我最近意识到我可以创建一个SQL函数来做同样的事情。(这是一个SQL函数,不是plpgsql) 我想知道在这种情况下,使用函数而不是选择函数是否有一个优势,主要是在花费的资源方面?请参阅下文,并提前感谢。我在这个网站的其他地方找不到关于这个话题的任何东西。(长时间阅读,第一次来电) 函数如下所示使用SQL函数而不是SELECT函数的优点,sql,postgresql,Sql,Postgresql,在Postgresql 9.0数据库中,我可以使用WHERE子句中的整数(profile_id)为带有SELECT语句的网页创建url 在过去,我只是在方便的时候进行选择,例如在视图中将子查询用作列/字段。但是我最近意识到我可以创建一个SQL函数来做同样的事情。(这是一个SQL函数,不是plpgsql) 我想知道在这种情况下,使用函数而不是选择函数是否有一个优势,主要是在花费的资源方面?请参阅下文,并提前感谢。我在这个网站的其他地方找不到关于这个话题的任何东西。(长时间阅读,第一次来电) 函数如
CREATE OR REPLACE FUNCTION msurl(integer)
RETURNS text AS
$BODY$
SELECT (('https://www.thenameofmywebsite/'::text ||
CASE
WHEN prof.type = 1 THEN 'm'::text
ELSE 'f'::text
END) || '/handler/'::text) || prof.profile_id AS profile_url
FROM profile prof
WHERE prof.profile_id = $1;
$BODY$
LANGUAGE sql
要获取我的url,我可以使用
SELECT prof.name,
SELECT (('https://www.thenameofmywebsite/'::text ||
CASE
WHEN prof.type = 1 THEN 'm'::text
ELSE 'f'::text
END) || '/handler/'::text) || prof.profile_id AS profile_url, prof.start_date
FROM profile prof,
WHERE prof.profile_id = id_number;
或者更整洁的版本:
SELECT prof.name, msurl(id_number) as profile_url, prof.start_date FROM profile prof;
函数的意义(sql函数)是封装。对于函数,SQL语句的某些片段具有名称、语义——您可以重用它,也可以构建一个库。没有任何其他好处,比如性能—它只会影响代码的可读性。您使用该函数的方式不会有任何优势—相反,它会大大降低您的选择速度。因为对于从主
select
语句(调用函数的语句)检索到的每一行,您都在同一个表上运行另一个select
当您想要封装构建url的逻辑时,函数确实具有优势。但您需要以不同的方式编写函数,以便通过将要使用的行传递给它来提高效率:
CREATE OR REPLACE FUNCTION msurl(profile)
RETURNS text AS
$BODY$
SELECT (('https://www.thenameofmywebsite/' ||
CASE
WHEN $1.type = 1 THEN 'm'
ELSE 'f'
END) || '/handler/' || $1.profile_id:: AS profile_url;
$BODY$
LANGUAGE sql;
另一个选项是分别传递您需要的所有列,但是通过传递行(类型),如果逻辑发生变化,并且您需要表中更多或更少的列,则不需要更改函数签名(以及对它的调用)
然后,您可以使用以下语法调用它:
SELECT prof.name,
msurl( (prof) ) as profile_url,
prof.start_date
FROM profile prof;
请注意,将别名传递给函数时,必须将其括在括号中(prof)
。此处的附加括号不是可选的
这样,函数仍然会为每一行调用,但它不会在profile
表上运行另一个select
由于Postgres以面向对象的方式处理此类函数,您甚至可以将其作为表的一列来调用:
SELECT prof.name,
prof.msurl as profile_url,
prof.start_date
FROM profile prof;
在本例中,由于对结果中的每一行都进行了额外的选择,该函数将对性能产生重大影响。它可以使用STABLE标志内联,但注释中有一个true。最好只编写标量SQL函数而不使用完整的内部选择