PLpgSQL使用时的注意事项

PL/pgSQL是PostgreSQL数据库系统的一个可加载的过程语言。 PL/pgSQL可以用于创建函数和触发器过程,为SQL语言增加控制结构,执行复杂的计算,继承所有用户定义类型、函数、操作符,定义为被服务器信任的语言,而且容易使用。

在PostgreSQL 9.0及其之后的版本中,PL/pgSQL是默认安装的。 

本文给出了PL/pgSQL在使用时的一些注意事项和使用建议。

PLpgSQL执行注意事项

1)会话中第一次执行PLpgSQL时,会被编译到抽象语法树(AST)中。而且每次执行时,都会伴随AST执行。

2)会话中第一次执行PLpgSQL时,会进行查询优化。每次执行时,都要进行查询的初始化和执行。

3)PLpgSQL 代码中的每个表达式都是查询。

4)不使用FROM,对应的是简单的表达式,更快的执行速度。

5)使用FROM从句,对应的是完整的查询,速度一般。

6)不要使用ISAM方式,ISAM方式是指索引顺序存取方法。

使用建议

综上所述,使用PLpgSQL时有以下几点建议:

1)尽可能在所有地方都使用简单的表达式。

2)不要使用无意义的查询。

3)不要使用ISAM方式。

4)不要包装查询。

还有一种情况是,由错误的数据类型导致的慢查询,举一个例子:

postgres=# EXPLAIN ANALYZE SELECT * FROM foo where id = 10;

                      QUERY PLAN                   

                                

--------------------------------------------------------------------------------

 Index Scan using foo_id_key on foo  (cost=0.42..8.44 rows=1 width=8) (actual ti

me=0.007..0.008 rows=1 loops=1)

   Index Cond: (id = 10)

 Planning time: 0.050 ms

 Execution time: 0.019 ms

(4 rows)

Time: 0.318 ms

postgres=# EXPLAIN ANALYZE SELECT * FROM foo where id = 10::numeric;

                      QUERY PLAN                

                                       

--------------------------------------------------------------------------------

 Gather  (cost=1000.00..12175.00 rows=5000 width=8) (actual time=0.179..256.782 

rows=1 loops=1)

   Workers Planned: 2

   Workers Launched: 2

   ->  Parallel Seq Scan on foo  (cost=0.00..10675.00 rows=2083 width=8) (actual

 time=162.239..247.032 rows=0 loops=3)

         Filter: ((id)::numeric = '10'::numeric)

         Rows Removed by Filter: 333333

 Planning time: 0.080 ms

 Execution time: 258.035 ms

(8 rows)

Time: 268.107 ms

这个示例展示了一种我们常犯的错误,即表中定义的id列的数据类型为int,但是变量却被声明为了numeric类型,由于数据类型错误,导致查询速度变慢。

PLpgSQL开发建议

1)不要将代码直接存储到数据库中,而是使用文件或者git的方式完成。

2)部署代码的过程中尽量使用rpm,deb等格式。

3)PLpgSQL开发比较好的工具有:

    plpgsql_check

    auto_explain

    PLpgSQL profiler

    pgAdmin(有完整的PLpgSQL debugger)

PLpgSQL使用建议

1)不要使用生命周期短的临时表(除非特别需要使用它),而是使用数组。

2)不要捕获所有的报错。

3)捕获异常不是毫无代价的,同样只在需要的时候这样做。

4)编写测试用例。

5)编写可读性高的代码,PLpgSQL在动态编码方便表现不佳,所以完全可以使用PLPerl, PLPython。

 

By Kalath

你可能感兴趣的:(PostgreSQL,Highgo,DB)