[WIP] Caching constant stable expressions per execution
От | Marti Raudsepp |
---|---|
Тема | [WIP] Caching constant stable expressions per execution |
Дата | |
Msg-id | CABRT9RC-1wGxZC_Z5mwkdk70fgY2DRX3sLXzdP4voBKuKPZDow@mail.gmail.com обсуждение исходный текст |
Ответы |
Re: [WIP] Caching constant stable expressions per execution
|
Список | pgsql-hackers |
Hi, This is a proof of concept patch for recognizing stable function calls with constant arguments and only calling them once per execution. I'm posting it to the list to gather feedback whether this is a dead end or not. Last time when this was brought up on the list, Tom Lane commented that doing the checks for constant folding probably outweigh the gains. http://archives.postgresql.org/pgsql-hackers/2010-11/msg01641.php Yesterday I was looking at evaluate_function(), where currently function constant folding happens, and realized that most of the knowledge needed to implement this for FuncExpr and OpExpr (and combinations thereof) is already there. This would probably cover 90% of the use cases with very little overhead. Other expression types can't be supported very well with this approach, notably case expressions and AND/OR/NOT. However, the code isn't very pretty. It works by changing evaluate_function() to recognize stable/immutable functions with constant stable/immutable arguments that aren't eligible for constant folding. It sets a new boolean attribute FuncExpr.stableconst which is checked during the function's first execution. If true, the result is stored in ExprState and evalfunc is replaced with a new one that returns the cached result. Most common use cases cover timestamptz expressions (because they are never immutable) such as: ts>=to_timestamp('2010-01-01', 'YYYY-MM-DD') ts>=(now() - interval '10 days') Typically an index on the column would marginalize performance lost by repeatedly evaluating the function. ---- Test data (1,051,777 rows, 38MB): create table ts as select generate_series(timestamptz '2001-01-01', '2011-01-01', '5min') ts; Test query (using pgbench -T 30, taking the best of 3 runs): select * from ts where ts>=to_timestamp('2001-01-01', 'YYYY-MM-DD') and ts<=to_timestamp('2001-01-01', 'YYYY-MM-DD'); Unpatched tps = 0.927458 Patched tps = 6.729378 There's even a measurable improvement from caching now() calls: select * from ts where ts>now(); Unpatched tps = 8.106439 Patched tps = 9.401684 Regards, Marti
Вложения
В списке pgsql-hackers по дате отправления: