LP#1549505: Precalculate attr_filter set, as it is very expensive in-view
authorMike Rylander <mrylander@gmail.com>
Tue, 1 Mar 2016 18:08:36 +0000 (13:08 -0500)
committerMike Rylander <mrylander@gmail.com>
Tue, 1 Mar 2016 18:08:36 +0000 (13:08 -0500)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.statisitcal-ratings.sql

index 1b59984..af12c19 100644 (file)
@@ -156,11 +156,6 @@ CREATE VIEW rating.generic_bib_population_global AS
                           FROM  actor.org_unit
                         ) x
                   GROUP BY 1
-            ),
-            badge_data AS (
-                SELECT  *,
-                        metabib.compile_composite_attr(COALESCE(attr_filter,'{}')) AS afilter
-                  FROM  rating.badge
             )
     SELECT  DISTINCT ON (b.id)
             b.id AS bib,
@@ -168,10 +163,9 @@ CREATE VIEW rating.generic_bib_population_global AS
             s.orgs
       FROM  biblio.record_entry b
             JOIN metabib.record_attr_vector_list r ON (b.id = r.source)
-            JOIN badge_data ON (
+            JOIN rating.badge badge_data ON (
                 badge_data.circ_mod_filter IS NULL
                 AND (badge_data.src_filter IS NULL OR b.source = badge_data.src_filter)
-                AND (badge_data.attr_filter IS NULL OR r.vlist @@ badge_data.afilter)
             )
             JOIN org_scope s ON (badge_data.scope = s.id);
 
@@ -184,11 +178,6 @@ CREATE VIEW rating.generic_bib_population_by_copy AS
                           FROM  actor.org_unit
                         ) x
                   GROUP BY 1
-            ),
-            badge_data AS (
-                SELECT  *,
-                        metabib.compile_composite_attr(COALESCE(attr_filter,'{}')) AS afilter
-                  FROM  rating.badge
             )
     SELECT  DISTINCT ON (b.id)
             b.id AS bib,
@@ -199,11 +188,10 @@ CREATE VIEW rating.generic_bib_population_by_copy AS
             JOIN asset.call_number cn ON (cn.record = b.id AND NOT cn.deleted)
             JOIN asset.copy cp ON (cp.call_number = cn.id AND NOT cp.deleted)
             JOIN org_scope s ON (cn.owning_lib = ANY (s.orgs))
-            JOIN badge_data ON (
+            JOIN rating.badge badge_data ON (
                 badge_data.scope = s.id
                 AND (badge_data.src_filter IS NULL OR b.source = badge_data.src_filter)
                 AND (badge_data.circ_mod_filter IS NULL OR cp.circ_modifier = badge_data.circ_mod_filter)
-                AND (badge_data.attr_filter IS NULL OR r.vlist @@ badge_data.afilter)
             )
             LEFT JOIN asset.copy_location_group_map lg ON (cp.location = lg.location)
       WHERE (badge_data.loc_grp_filter IS NULL OR lg.lgroup = badge_data.loc_grp_filter);
@@ -217,11 +205,6 @@ CREATE VIEW rating.generic_bib_population_by_uri AS
                           FROM  actor.org_unit
                         ) x
                   GROUP BY 1
-            ),
-            badge_data AS (
-                SELECT  *,
-                        metabib.compile_composite_attr(COALESCE(attr_filter,'{}')) AS afilter
-                  FROM  rating.badge
             )
     SELECT  DISTINCT ON (b.id)
             b.id AS bib,
@@ -233,11 +216,10 @@ CREATE VIEW rating.generic_bib_population_by_uri AS
             JOIN asset.uri_call_number_map urim ON (urim.call_number = cn.id)
             JOIN asset.uri uri ON (urim.uri = uri.id AND uri.active)
             JOIN org_scope s ON (cn.owning_lib = ANY (s.orgs))
-            JOIN badge_data ON (
+            JOIN rating.badge badge_data ON (
                 badge_data.scope = s.id
                 AND badge_data.circ_mod_filter IS NULL
                 AND (badge_data.src_filter IS NULL OR b.source = badge_data.src_filter)
-                AND (badge_data.attr_filter IS NULL OR r.vlist @@ badge_data.afilter)
             );
 
 CREATE VIEW rating.generic_bib_population_by_copy_or_uri AS
@@ -249,11 +231,6 @@ CREATE VIEW rating.generic_bib_population_by_copy_or_uri AS
                           FROM  actor.org_unit
                         ) x
                   GROUP BY 1
-            ),
-            badge_data AS (
-                SELECT  *,
-                        metabib.compile_composite_attr(COALESCE(attr_filter,'{}')) AS afilter
-                  FROM  rating.badge
             )
     SELECT  DISTINCT ON (b.id)
             b.id AS bib,
@@ -263,10 +240,9 @@ CREATE VIEW rating.generic_bib_population_by_copy_or_uri AS
             JOIN metabib.record_attr_vector_list r ON (b.id = r.source)
             JOIN asset.call_number cn ON (cn.record = b.id AND NOT cn.deleted)
             JOIN org_scope s ON (cn.owning_lib = ANY (s.orgs))
-            JOIN badge_data ON (
+            JOIN rating.badge badge_data ON (
                 badge_data.scope = s.id
                 AND (badge_data.src_filter IS NULL OR b.source = badge_data.src_filter)
-                AND (badge_data.attr_filter IS NULL OR r.vlist @@ badge_data.afilter)
             )
             LEFT JOIN asset.copy cp ON (cp.call_number = cn.id AND NOT cp.deleted)
             LEFT JOIN asset.uri_call_number_map urim ON (urim.call_number = cn.id)
@@ -287,6 +263,9 @@ BEGIN
     SELECT * INTO badge_row FROM rating.badge WHERE id = badge_id;
     SELECT * INTO param FROM rating.popularity_parameter WHERE id = badge_row.popularity_parameter;
 
+    -- Calculate the attribute filter set, or all bibs if none
+    PERFORM rating.precalc_attr_filter(badge_row.attr_filter);
+
     -- If it's a fixed-rating badge, just do it ...
     IF badge_row.fixed_rating IS NOT NULL THEN
         DELETE FROM rating.record_badge_score WHERE badge = badge_id;
@@ -353,6 +332,33 @@ BEGIN
 END;
 $f$ LANGUAGE PLPGSQL;
 
+-- all or limited...
+CREATE OR REPLACE FUNCTION rating.precalc_attr_filter(attr_filter TEXT)
+    RETURNS INT AS $f$
+DECLARE
+    cnt     INT     := 0;
+    afilter TEXT    := 0;
+BEGIN
+
+    DROP TABLE IF EXISTS precalc_attr_filter_bib_list;
+    IF attr_filter IS NOT NULL THEN
+        afilter := metabib.compile_composite_attr(attr_filter);
+        CREATE TEMP TABLE precalc_attr_filter_bib_list ON COMMIT DROP AS
+            SELECT source AS id FROM metabib.record_attr_vector_list
+            WHERE vlist @@ metabib.compile_composite_attr(attr_filter);
+    ELSE
+        CREATE TEMP TABLE precalc_attr_filter_bib_list ON COMMIT DROP AS
+            SELECT source AS id FROM metabib.record_attr_vector_list;
+    END IF
+
+    CREATE INDEX precalc_attr_filter_bib_list_idx
+        ON precalc_attr_filter_bib_list (id);
+
+    SELECT count(*) INTO cnt FROM precalc_attr_filter_bib_list;
+    RETURN cnt;
+END;
+$f$ LANGUAGE PLPGSQL;
+
 CREATE OR REPLACE FUNCTION rating.holds_filled_over_time(badge_id INT)
     RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
 DECLARE
@@ -387,6 +393,7 @@ BEGIN
                 COUNT(h.id)::INT AS holds
           FROM  action.hold_request h
                 JOIN reporter.hold_request_record rhrr ON (rhrr.id = h.id)
+                JOIN precalc_attr_filter_bib_list f ON (f.id = rhrr.bib_record)
                 JOIN rating.generic_bib_population_by_copy pop ON (rhrr.bib_record = pop.bib AND pop.badge = badge.id)
           WHERE h.fulfillment_time >= NOW() - badge.horizon_age
                 AND h.request_lib = ANY (pop.orgs)
@@ -430,6 +437,7 @@ BEGIN
                 COUNT(h.id)::INT AS holds
           FROM  action.hold_request h
                 JOIN reporter.hold_request_record rhrr ON (rhrr.id = h.id)
+                JOIN precalc_attr_filter_bib_list f ON (f.id = rhrr.bib_record)
                 JOIN rating.generic_bib_population_by_copy pop ON (rhrr.bib_record = pop.bib AND pop.badge = badge.id)
           WHERE h.request_time >= NOW() - badge.horizon_age
                 AND h.request_lib = ANY (pop.orgs)
@@ -445,6 +453,7 @@ CREATE OR REPLACE FUNCTION rating.current_hold_count(INT)
             COUNT(h.id)::NUMERIC AS holds
       FROM  action.hold_request h
             JOIN reporter.hold_request_record rhrr ON (rhrr.id = h.id)
+            JOIN precalc_attr_filter_bib_list f ON (f.id = rhrr.bib_record)
             JOIN rating.generic_bib_population_by_copy pop ON (rhrr.bib_record = pop.bib AND pop.badge = $1)
       WHERE h.fulfillment_time IS NULL
             AND h.request_lib = ANY (pop.orgs)
@@ -486,6 +495,7 @@ BEGIN
           FROM  action.circulation c
                 JOIN asset.copy cp ON (cp.id = c.target_copy)
                 JOIN asset.call_number cn ON (cn.id = cp.call_number)
+                JOIN precalc_attr_filter_bib_list f ON (f.id = cn.record)
                 JOIN rating.generic_bib_population_by_copy pop ON (cn.record = pop.bib AND pop.badge = badge.id)
           WHERE c.xact_start >= NOW() - badge.horizon_age
                 AND cn.owning_lib = ANY (pop.orgs)
@@ -505,6 +515,7 @@ CREATE OR REPLACE FUNCTION rating.current_circ_count(INT)
       FROM  action.circulation c
             JOIN asset.copy cp ON (cp.id = c.target_copy)
             JOIN asset.call_number cn ON (cn.id = cp.call_number)
+            JOIN precalc_attr_filter_bib_list f ON (f.id = cn.record)
             JOIN rating.generic_bib_population_by_copy pop ON (cn.record = pop.bib AND pop.badge = $1)
       WHERE c.checkin_time IS NULL
             AND cn.owning_lib = ANY (pop.orgs)
@@ -520,6 +531,7 @@ CREATE OR REPLACE FUNCTION rating.checked_out_total_ratio(INT)
                     1 AS total
               FROM  asset.copy cp
                     JOIN asset.call_number cn ON (cn.id = cp.call_number)
+                    JOIN precalc_attr_filter_bib_list f ON (f.id = cn.record)
                     JOIN rating.generic_bib_population_by_copy pop ON (cn.record = pop.bib AND pop.badge = $1)
               WHERE cn.owning_lib = ANY (pop.orgs)
             ) x
@@ -532,6 +544,7 @@ CREATE OR REPLACE FUNCTION rating.holds_total_ratio(INT)
             COUNT(DISTINCT m.hold)::NUMERIC / COUNT(DISTINCT cp.id)::NUMERIC
       FROM  asset.copy cp
             JOIN asset.call_number cn ON (cn.id = cp.call_number)
+            JOIN precalc_attr_filter_bib_list f ON (f.id = cn.record)
             JOIN rating.generic_bib_population_by_copy pop ON (cn.record = pop.bib AND pop.badge = $1)
             LEFT JOIN action.hold_copy_map m ON (m.target_copy = cp.id)
       WHERE cn.owning_lib = ANY (pop.orgs)
@@ -546,6 +559,7 @@ CREATE OR REPLACE FUNCTION rating.holds_holdable_ratio(INT)
             JOIN asset.copy_location cl ON (cl.id = cp.location)
             JOIN config.copy_status cs ON (cs.id = cp.status)
             JOIN asset.call_number cn ON (cn.id = cp.call_number)
+            JOIN precalc_attr_filter_bib_list f ON (f.id = cn.record)
             JOIN rating.generic_bib_population_by_copy pop ON (cn.record = pop.bib AND pop.badge = $1)
             LEFT JOIN action.hold_copy_map m ON (m.target_copy = cp.id)
       WHERE cn.owning_lib = ANY (pop.orgs)
@@ -561,6 +575,7 @@ CREATE OR REPLACE FUNCTION rating.bib_record_age(INT)
             1.0 / EXTRACT(EPOCH FROM AGE(b.create_date))::NUMERIC + 1.0
       FROM  rating.generic_bib_population_by_copy_or_uri pop
             JOIN biblio.record_entry b ON (b.id = pop.bib)
+            JOIN precalc_attr_filter_bib_list f ON (f.id = b.id)
       WHERE pop.badge = $1
 $f$ LANGUAGE SQL STABLE STRICT;
 
@@ -569,6 +584,7 @@ CREATE OR REPLACE FUNCTION rating.bib_pub_age(INT)
     SELECT  pop.bib AS bib,
             s.value::NUMERIC
       FROM  rating.generic_bib_population_by_copy_or_uri pop
+            JOIN precalc_attr_filter_bib_list f ON (f.id = pop.bib)
             JOIN metabib.record_sorter s ON (
                 s.source = pop.bib
                 AND s.attr = 'pubdate'
@@ -595,6 +611,7 @@ CREATE OR REPLACE FUNCTION rating.percent_time_circulating(INT)
                     )::NUMERIC AS circ_time
               FROM  asset.copy cp
                     JOIN asset.call_number cn ON (cn.id = cp.call_number)
+                    JOIN precalc_attr_filter_bib_list f ON (f.id = cn.record)
                     JOIN rating.generic_bib_population_by_copy pop ON (cn.record = pop.bib AND pop.badge = $1)
                     LEFT JOIN action.all_circulation circ ON (circ.target_copy = cp.id)
               WHERE cn.owning_lib = ANY (pop.orgs)
@@ -607,6 +624,7 @@ CREATE OR REPLACE FUNCTION rating.generic_fixed_rating_by_copy(INT)
     RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
 SELECT bib, 1.0
   FROM  rating.generic_bib_population_by_copy pop
+        JOIN precalc_attr_filter_bib_list f ON (f.id = pop.bib)
   WHERE pop.badge = $1;
 $f$ LANGUAGE SQL STABLE STRICT;
 
@@ -614,6 +632,7 @@ CREATE OR REPLACE FUNCTION rating.generic_fixed_rating_by_uri(INT)
     RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
 SELECT bib, 1.0
   FROM  rating.generic_bib_population_by_uri pop
+        JOIN precalc_attr_filter_bib_list f ON (f.id = pop.bib)
   WHERE pop.badge = $1;
 $f$ LANGUAGE SQL STABLE STRICT;
 
@@ -621,6 +640,7 @@ CREATE OR REPLACE FUNCTION rating.generic_fixed_rating_global(INT)
     RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
 SELECT bib, 1.0
   FROM  rating.generic_bib_population_global pop
+        JOIN precalc_attr_filter_bib_list f ON (f.id = pop.bib)
   WHERE pop.badge = $1;
 $f$ LANGUAGE SQL STABLE STRICT;