Hi, I need to optimise and aggregate array integer values in a function and i am doing this by below stored function :
-- type def CREATE TYPE fun_type AS ( g_id integer, zip_id_list integer[], city_id_list integer[], state_id_list integer[], lat_long_id_list bigint[], country_id_list bigint[], ccid_list bigint[], cr_id_list bigint[], is_active boolean ); -- fun def CREATE OR REPLACE FUNCTION fun_multicountry() RETURNS SETOF fun_type AS $BODY$ DECLARE row1 fun_type%ROWTYPE; dt1 record; dt1outer record; BEGIN FOR dt1outer IN SELECT DISTINCT g_id FROM tableA LOOP row1.country_id_list = '{}'; row1.state_id_list = '{}'; row1.city_id_list = '{}'; row1.lat_long_id_list = '{}'; row1.zip_id_list = '{}'; row1.ccid_list = '{}'; row1.cr_id_list = '{}'; row1.g_id = dt1outer.g_id; row1.is_active = false; FOR dt1 IN SELECT * FROM tableA LEFT OUTER JOIN tableB ON (pr_id = tableB.id) where g_id = *dt1outer.g_id* AND tableA.is_active = true LOOP row1.is_active = true; IF(dt1.geot_type_id =1 and dt1.pr_id is not NULL) THEN row1.cr_id_list = row1.cr_id_list|| dt1.targeting_ids; ELSIF( (dt1.state_id_list is null or dt1.state_id_list = '{}') AND (dt1.city_id_list is null or dt1.city_id_list = '{}') AND (dt1.lat_long_id_list is null or dt1.lat_long_id_list = '{}') AND (dt1.zip_id_list is null or dt1.zip_id_list = '{}')) THEN row1.country_id_list = row1.country_id_list || dt1.country_id; ELSE row1.state_id_list = row1.state_id_list || dt1.state_id_list; row1.city_id_list = row1.city_id_list || dt1.city_id_list; row1.lat_long_id_list = row1.lat_long_id_list || dt1.lat_long_id_list; row1.zip_id_list = row1.zip_id_list || dt1.zip_id_list; END IF; IF(dt1.ccid_list is null or dt1.ccid_list = '{}') THEN row1.ccid_list = row1.ccid_list || -dt1.country_id; ELSE row1.ccid_list = row1.ccid_list || dt1.ccid_list; END IF; END LOOP; return NEXT row1; END LOOP; END $BODY$ LANGUAGE plpgsql VOLATILE COST 100 ROWS 1000; Above function is taking ~ 30 -40 sec to finish where as table rows are : explain analyze select fun_multicountry(); QUERY PLAN ---------------------------------------------------------------------------------------------------- Result (cost=0.00..5.25 rows=1000 width=0) (actual time=21855.881..21959.683 rows=420286 loops=1) Total runtime: 31977.712 ms (2 rows) Time: 21978.103 ms select count(*) from tableA; count -------- 629439 (1 row) Time: 135.858 ms select count(*) from tableB; count ------- 841 select count(distinct g_id) from tableA; count -------- 420287 I need to aggregate all different array values in table depending upon above if conditions and return them. Is dere any optimal approach to do this as i am calling this function in many other functions and its just adding to slowness. I am trying to rewrite using CASE statements. Will this help ? Please let me know if there is any optimal way to finish this function in ~ 2-3 secs Thanks