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. :)