Thread: spurious function execution in prepared statements.
OK, I have a situation that might be a performance problem, a bug, or an unavoidable consequence of using prepared statements. The short version is that I am getting function executions for rows not returned in a result set when they are in a prepared statement. In other words, I have a query: select f(t.c) from t where [boolean expr on t] limit 1; because of the limit phrase, obviously, at most one record is returned and f executes at most once regardless of the plan used (in practice, sometimes index, sometimes seq_scan. Now, if the same query is executed as a prepared statement, prepare ps(...) as select f(t.c) from t where [expr] limit 1; execute ps; now, if ps ends up using a index scan on t, everything is ok. However, if ps does a seqscan, f executes for every row on t examined until the [expr] criteria is met. Is this a bug? If necessary I should be able to set up a reproducible example. The easy workaround is to not use prepared statements in these situations, but I need to be able to guarantee that f only executes once (even if that means exploring subqueries). Merlin
On Thu, Sep 30, 2004 at 09:45:51AM -0400, Merlin Moncure wrote: > Now, if the same query is executed as a prepared statement, > prepare ps(...) as select f(t.c) from t where [expr] limit 1; > execute ps; > > now, if ps ends up using a index scan on t, everything is ok. However, > if ps does a seqscan, f executes for every row on t examined until the > [expr] criteria is met. Is this a bug? If necessary I should be able > to set up a reproducible example. The easy workaround is to not use > prepared statements in these situations, but I need to be able to > guarantee that f only executes once (even if that means exploring > subqueries). Here's another workaround that may let you use a prepared statement: prepare ps(...) as select f(c) from (select c from t where [expr] limit 1) as t1 -Mike
> Here's another workaround that may let you use a prepared statement: > > prepare ps(...) as > select f(c) from (select c from t where [expr] limit 1) as t1 > > -Mike I was just exploring that. In fact, the problem is not limited to prepared statements...it's just that they are more likely to run a seqscan so I noticed it there first. Since I am in a situation where I need very strict control over when and why f gets executed, I pretty much have to go with the subquery option. That said, it just seems that out of result set excecutions of f should be in violation of something... Merlin
On Thu, 30 Sep 2004, Merlin Moncure wrote: > OK, I have a situation that might be a performance problem, a bug, or an > unavoidable consequence of using prepared statements. The short version > is that I am getting function executions for rows not returned in a > result set when they are in a prepared statement. > > In other words, I have a query: > select f(t.c) from t where [boolean expr on t] limit 1; An actual boolean expr on t? Or on a column in t? > because of the limit phrase, obviously, at most one record is returned > and f executes at most once regardless of the plan used (in practice, > sometimes index, sometimes seq_scan. > > Now, if the same query is executed as a prepared statement, > prepare ps(...) as select f(t.c) from t where [expr] limit 1; > execute ps; > > now, if ps ends up using a index scan on t, everything is ok. However, > if ps does a seqscan, f executes for every row on t examined until the > [expr] criteria is met. Is this a bug? If necessary I should be able > to set up a reproducible example. The easy workaround is to not use > prepared statements in these situations, but I need to be able to > guarantee that f only executes once (even if that means exploring > subqueries). I think a reproducible example would be good. Simple attempts to duplicate this on 8.0b2 have failed for me, unless I'm using order by.
"Merlin Moncure" <merlin.moncure@rcsonline.com> writes: > now, if ps ends up using a index scan on t, everything is ok. However, > if ps does a seqscan, f executes for every row on t examined until the > [expr] criteria is met. Is this a bug? Works for me. regression=# create function f(int) returns int as ' regression'# begin regression'# raise notice ''f(%)'', $1; regression'# return $1; regression'# end' language plpgsql; CREATE FUNCTION regression=# select f(unique2) from tenk1 where unique2%2 = 1 limit 2; NOTICE: f(1) NOTICE: f(3) f --- 1 3 (2 rows) regression=# prepare ps as regression-# select f(unique2) from tenk1 where unique2%2 = 1 limit 2; PREPARE regression=# execute ps; NOTICE: f(1) NOTICE: f(3) f --- 1 3 (2 rows) regression=# You sure you aren't using f() in the WHERE clause? regards, tom lane