thanks.. I will try creating that function. :)

- Greg

-----Original Message-----
From: Tom Lane [mailto:[EMAIL PROTECTED]]
Sent: Friday, May 12, 2000 8:24 AM
To: Gregory Krasnow
Cc: Bruce Momjian; [EMAIL PROTECTED]
Subject: Re: [GENERAL] backend running out of memory in v7.0 


Gregory Krasnow <[EMAIL PROTECTED]> writes:
> typical query produced from this product (I didn't write the piece that
> creates the queries, and I know that the queries could definitely be
> optimized):

>  SELECT cms_users.usr_id 
>  FROM cms_usr_prof, cms_usr_incenvalue, cms_opt_in, cms_users,
> cms_usr_prodvalue
>  WHERE (((cms_usr_prof.cluster_id2=2) OR (cms_usr_prof.cluster_id2=7))
>  OR ((cms_usr_incenvalue.incenvalue_id=283 AND cms_usr_prodvalue.num_sol >
> 0) OR (cms_usr_incenvalue.incenvalue_id=283 AND cms_usr_prodvalue.num_resp
>
> 0))
>  OR (cms_usr_prof.last_visit_dt< (now() - 3)::datetime AND
cms_usr_prof.last_visit_dt> = (now() - 4)::datetime)
>  OR (cms_opt_in.optin_creation_date>= (now() - 14)::datetime)
>  OR (cms_usr_prof.sum_resp_time/cms_usr_prof.total_unq_resp >= 2 AND
> cms_usr_prof.sum_resp_time/cms_usr_prof.total_unq_resp < 3 AND
cms_usr_prof.total_unq_resp> 0)
>  OR (cms_users.usr_age>=21 AND cms_users.usr_age<=25)
>  OR ((cms_users.usr_bmonth=1) OR (cms_users.usr_bmonth=2) OR
> (cms_users.usr_bmonth=3) OR (cms_users.usr_bmonth=4) OR
> [ etc etc ]

OK, I can well believe that this would've thrown the 6.5 planner for a
loop ;-).  But 7.0's planner should cope.  Try running this through
EXPLAIN and see if you get a query plan back (in a reasonable amount
of time and memory usage).  You would not have under 6.5, I think.

Assuming that you do, that leaves us with the expression memory leakage
theory, and I see the cause right there: the three expressions like
(now() - 3)::datetime.  Since datetime is a pass-by-reference type,
you chew up sizeof(datetime) every time this is evaluated.  What's
worse, it'll be evaluated again for every tuple that's processed,
because the system doesn't think it can constant-fold an expression
involving now().  Process enough tuples, and you run out of memory
before the system gets around to reclaiming the temporary space.

The expressions in

>  OR (cms_usr_prof.sum_resp_time/cms_usr_prof.total_unq_resp >= 2 AND
> cms_usr_prof.sum_resp_time/cms_usr_prof.total_unq_resp < 3 AND

might also be causing a problem depending on what datatype is involved.
It'd be safe enough if these fields are all int.

If you are not in a position to modify the app generating the query at
all, then I think you are kind of stuck until 7.1.  You could maybe
kluge it to work by marking now() and timestamp_mi_span() as cacheable
but that could have bad consequences for other queries.

If you can modify the queries, then you could eliminate the leakage
from re-evaluation of the datetime expressions by creating a cacheable
user-defined function that produces the right result.  I posted a
detailed example a few days ago in one pgsql list or another; check
the archives.  Basically you want to define "ndaysago(int) returns
timestamp" so that the optimizer can't see that there are any
uncacheable functions involved; then it'll evaluate the subexpressions
just once at query start.

                        regards, tom lane

Reply via email to