postgresql函数或查询性能

时间:2014-05-14 09:42:17

标签: sql postgresql

我对执行Postgres函数有一些常规查询。我最近注意到,如果我将任何算术或业务操作的输出存储在变量中,然后在查询中执行时调用它,而不是在时间执行操作执行它节省了很多时间。

但是我并不知道在Postgres的新手中,通常会采取任何措施来缩短所花费的时间并提高性能。

2 个答案:

答案 0 :(得分:2)

注意读 - 修改 - 写周期和事务异常。

只要您仔细考虑缓存它的范围和缓存失效,就可以在本地缓存值。在您阅读它的交易的生命周期内存储值时要非常小心。

读 - 修改 - 写

除非SELECT ... FOR UPDATE在写入期间保持打开的事务中的值SERIALIZABLE,否则还必须小心不要将该缓存值用作写回数据库的计算的输入,使用{ {1}}交易,或您使用某种形式的optimistic concurrency control

如果你不小心你可以让自己陷入困境,经典就像银行并发例子,其中账户id = 1将$ 100转移到账户id = 2和id = 3:

session1                                  session2

begin;                                    begin;

select balance 
from account
where id=1;  => 100

                                          select balance
                                          from account
                                          where id = 1;   => 100

update account
set balance = balance + 100
where id = 2;  -- this is safe


                                          update account
                                          set balance = balance + 100
                                          where id = 3;  -- this is safe

update account
set balance = 0 -- 100 - 100 = 0
where id = 1;

                                          update account
                                          set balance = 0 -- 100 - 100 = 0
                                          where id = 1;

commit;
                                          commit;

糟糕!你刚刚为两个人的帐户增加了100美元,但只花了100美元的id = 1。针对id = 2和id = 3的更新是正常的,因为它们对余额(balance = balance + 100)进行了就地修改。对id = 1的更新不是,因为它们读取了值,修改了它的客户端,并写了一个新的值。

这就是我所说的读 - 修改 - 写周期。

如果我们在阅读余额时使用SELECT ... FOR UPDATE,那将是安全的,因为第二次交易将一直停留到第一次交易。但如果我们避免了读取 - 写入 - 写入周期并且就地完成了更新,那将会更好。

缓存

缓存很好 - 但是当基础数据更新但是你的缓存没有被刷新和刷新时会引入异常。

缓存失效通常是一个难题,但Pg有一些帮助的工具。

特别是,从触发器调用的listennotify可用于通过助手守护程序急切地从存储在memcached / redis /中的缓存中刷新数据。这意味着你不太可能必须刷新大块缓存,或者在发生变化时丢弃整个缓存。

您还需要决定过时的事情是否过时。有时你只是不在乎过时5秒的值。还是半个小时。或一周。这取决于应用程序,相关数据等。

答案 1 :(得分:0)

将值存储在变量中没有什么特别的错误。

如果您正在存储值,那么您可以按程序,逐步的方式而不是面向集合的方式编写SQL,那么您最好不要这样做。 SQL是一种面向集合的语言;如果你编写面向集合的SQL,它通常会表现得更好。

存储值并在以后使用它们的风险是,自存储它们以来,这些值的基础数据可能已经发生了变化。这是一个真正的问题是特定于应用程序,但通常 是一个最好避免的问题。