Re: SQL Function performance - Mailing list pgsql-performance
From | Jim C. Nasby |
---|---|
Subject | Re: SQL Function performance |
Date | |
Msg-id | 20051004205225.GX40138@pervasive.com Whole thread Raw |
In response to | SQL Function performance (<adnandursun@asrinbilisim.com.tr>) |
List | pgsql-performance |
On Thu, Sep 29, 2005 at 10:54:58PM +0300, adnandursun@asrinbilisim.com.tr wrote: > Hi All, > > I have a SQL function like : > > CREATE OR REPLACE FUNCTION > fn_get_yetkili_inisyer_listesi(int4, int4) > RETURNS SETOF kod_adi_liste_type AS > $BODY$ > SELECT Y.KOD,Y.ADI > FROM T_YER Y > WHERE EXISTS (SELECT 1 > FROM T_GUZER G > WHERE (G.BIN_YER_KOD = $1 OR COALESCE($1,0)=0) > AND FN_FIRMA_ISVISIBLE(G.FIRMA_NO,$2) = 1 > AND G.IN_YER_KOD = Y.KOD) > AND Y.IPTAL = 'H'; > $BODY$ > LANGUAGE 'sql' VOLATILE; > > When i use like "SELECT * FROM > fn_get_yetkili_inisyer_listesi(1, 3474)" and > planner result is "Function Scan on > fn_get_yetkili_inisyer_listesi (cost=0.00..12.50 rows=1000 > width=36) (1 row) " and it runs very slow. > > But when i use like > > "SELECT Y.KOD,Y.ADI > FROM T_YER Y > WHERE EXISTS (SELECT 1 > FROM T_GUZER G > WHERE (G.BIN_YER_KOD > = 1 OR COALESCE(1,0)=0) > AND FN_FIRMA_ISVISIBLE(G.FIRMA_NO,3474) = 1 > AND G.IN_YER_KOD = Y.KOD) > AND Y.IPTAL = 'H';" > > planner result : > > " > QUERY PLAN > > -------------------------------------------------------------------------------- > ----------------------------- > Seq Scan on t_yer y (cost=0.00..3307.79 rows=58 width=14) > Filter: (((iptal)::text = 'H'::text) AND (subplan)) > SubPlan > -> Index Scan using > t_guzer_ucret_giris_performans_idx on t_guzer g (cost > =0.00..28.73 rows=1 width=0) > Index Cond: ((bin_yer_kod = 1) AND (in_yer_kod = > $0)) > Filter: (fn_firma_isvisible(firma_no, 3474) = 1) > (6 rows) > " > and it runs very fast. > > Any idea ? Need EXPLAIN ANALYZE. I suspect this is due to a cached query plan. PostgreSQL will cache a query plan for the SELECT the first time you run the function and that plan will be re-used. Depending on what data you call the function with, you could get a very different plan. Also, you might do better with a JOIN instead of using EXISTS. You can also make this function STABLE instead of VOLATILE. Likewise, if FN_FIRMA_ISVISIBLE can't change any data, you can also make it STABLE which would likely improve the performance of the query. But neither of these ideas would account for the difference between function performance and raw query performance. On a side note, if OR $1 IS NULL works that will be more readable (and probably faster) than the OR COALESCE($1,0)=0. -- Jim C. Nasby, Sr. Engineering Consultant jnasby@pervasive.com Pervasive Software http://pervasive.com work: 512-231-6117 vcard: http://jim.nasby.net/pervasive.vcf cell: 512-569-9461
pgsql-performance by date: