CREATE FUNCTION apply_billing_stop_function() RETURNS TRIGGER AS $apply_billing_stop_function$ DECLARE result RECORD; BEGIN // Problem SELECT which I believe is source of long execution time SELECT route, class, destid, description, init, inc, rate, cost, CEIL(NEW.duration::float / routes.inc) * routes.inc AS billtime, ((CEIL(NEW.duration::float / routes.inc) * routes.inc)::float / 60) * routes.rate AS total INTO result FROM routes WHERE routes.class = (SELECT class FROM clients WHERE prefix = NEW.prefix) AND SUBSTR(NEW.callee, (CASE WHEN (SELECT strip1 FROM providers WHERE destid = routes.destid) AND SUBSTR(NEW.callee, 1, 1) = '1' THEN 2 ELSE 1 END)) LIKE routes.route || '%' AND active ORDER BY routes.route DESC, routes.rate ASC LIMIT 1; IF result.billtime < result.init AND result.billtime > 0 THEN result.billtime := result.init; END IF; NEW.client := (SELECT name FROM clients WHERE prefix = NEW.prefix); NEW.route := result.route; NEW.class := result.class; NEW.description := result.description; NEW.init := result.init; NEW.inc := result.inc; NEW.billtime := result.billtime; NEW.rate := result.rate; NEW.cost := result.cost; NEW.total := result.total; DELETE FROM cdrs_current WHERE channel = NEW.channel; RETURN NEW; END; $apply_billing_stop_function$ LANGUAGE 'plpgsql'; CREATE TRIGGER apply_billing_stop BEFORE INSERT ON cdrs FOR EACH ROW EXECUTE PROCEDURE apply_billing_stop_function(); QUERY PLAN for SELECT in TRIGGER executed from CLI (No PREPARE, not sure if necessary) -------------------------------------------------------------------------------------------------------------------- Limit (cost=6380.77..6380.77 rows=1 width=57) (actual time=83.238..83.239 rows=1 loops=1) InitPlan -> Seq Scan on clients (cost=0.00..15.75 rows=2 width=4) (actual time=0.009..0.013 rows=1 loops=1) Filter: ((prefix)::text = '369369'::text) -> Sort (cost=6365.02..6366.25 rows=495 width=57) (actual time=83.234..83.234 rows=1 loops=1) Sort Key: route, rate -> Seq Scan on routes (cost=0.00..6342.86 rows=495 width=57) (actual time=17.164..83.216 rows=1 loops=1) Filter: (("class" = $0) AND ('4254556000'::text ~~ ((route)::text || '%'::text)) AND active) Table "public.cdrs" Column | Type | Modifiers -------------+-----------------------------+----------- direction | character varying | protocol | character varying | channel | integer | prefix | character varying | client | character varying | duration | double precision | ringtime | double precision | code | integer | endedby | character varying | caller | character varying | callee | character varying | host | character varying | gateway | character varying | route | character varying | class | integer | description | character varying | init | integer | inc | integer | billtime | integer | rate | double precision | cost | double precision | total | double precision | starttime | timestamp without time zone | stoptime | timestamp without time zone | Triggers: apply_billing_stop BEFORE INSERT ON cdrs FOR EACH ROW EXECUTE PROCEDURE apply_billing_stop_function() Table "public.clients" Column | Type | Modifiers -------------+-------------------+----------- name | character varying | prefix | character varying | class | integer | rtp_forward | character varying | type | character varying | balance | double precision | active | boolean | Table "public.providers" Column | Type | Modifiers ----------+-------------------+----------- destid | integer | name | character varying | alias | character varying | prefix | character varying | protocol | character varying | host | character varying | port | integer | strip1 | boolean | active | boolean | Table "public.routes" Column | Type | Modifiers -------------+-------------------+----------- route | character varying | not null lata | character varying | ocn | character varying | rate | double precision | cost | double precision | init | integer | inc | integer | city | character varying | state | character varying | country | character varying | description | character varying | class | integer | destid | integer | active | boolean | Indexes: "routes_pkey" PRIMARY KEY, btree (route) Any help would be hugely appreciated. :)