diff --git a/src/manage_pg.c b/src/manage_pg.c index eb78ba23b..f5806e13a 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -1452,11 +1452,16 @@ manage_create_sql_functions () " FROM tasks WHERE id = $1)" " THEN CAST (NULL AS double precision)" " ELSE" - " (SELECT report_severity ((SELECT id FROM reports" - " WHERE task = $1" - " AND scan_run_status = %u" - " ORDER BY creation_time DESC" - " LIMIT 1 OFFSET 0), $2, $3))" + /* Only look up the severity when the task has a report. Calling + * report_severity with NULL returns NULL as well, but it costs a + * full evaluation of the severity query for every task that never + * ran, which dominates aggregates over many tasks. */ + " (SELECT report_severity (last_report.id, $2, $3)" + " FROM (SELECT id FROM reports" + " WHERE task = $1" + " AND scan_run_status = %u" + " ORDER BY creation_time DESC" + " LIMIT 1 OFFSET 0) AS last_report)" " END;" "$$ LANGUAGE SQL;", TASK_STATUS_DONE); @@ -1477,11 +1482,16 @@ manage_create_sql_functions () " FROM tasks WHERE id = $1)" " THEN CAST (NULL AS double precision)" " ELSE" - " (SELECT report_severity ((SELECT id FROM reports" - " WHERE task = $1" - " AND scan_run_status = %u" - " ORDER BY creation_time DESC" - " LIMIT 1 OFFSET 0), $2, $3))" + /* Only look up the severity when the task has a report. Calling + * report_severity with NULL returns NULL as well, but it costs a + * full evaluation of the severity query for every task that never + * ran, which dominates aggregates over many tasks. */ + " (SELECT report_severity (last_report.id, $2, $3)" + " FROM (SELECT id FROM reports" + " WHERE task = $1" + " AND scan_run_status = %u" + " ORDER BY creation_time DESC" + " LIMIT 1 OFFSET 0) AS last_report)" " END;" "$$ LANGUAGE SQL;", TASK_STATUS_DONE); @@ -1499,11 +1509,16 @@ manage_create_sql_functions () " FROM tasks WHERE id = $1)" " THEN CAST (NULL AS double precision)" " ELSE" - " (SELECT report_severity ((SELECT id FROM reports" - " WHERE task = $1" - " AND scan_run_status = %u" - " ORDER BY creation_time DESC" - " LIMIT 1 OFFSET 0), $2, $3))" + /* Only look up the severity when the task has a report. Calling + * report_severity with NULL returns NULL as well, but it costs a + * full evaluation of the severity query for every task that never + * ran, which dominates aggregates over many tasks. */ + " (SELECT report_severity (last_report.id, $2, $3)" + " FROM (SELECT id FROM reports" + " WHERE task = $1" + " AND scan_run_status = %u" + " ORDER BY creation_time DESC" + " LIMIT 1 OFFSET 0) AS last_report)" " END;" "$$ LANGUAGE SQL;", TASK_STATUS_DONE); @@ -1521,11 +1536,16 @@ manage_create_sql_functions () " FROM tasks WHERE id = $1)" " THEN CAST (NULL AS double precision)" " ELSE" - " (SELECT report_severity ((SELECT id FROM reports" - " WHERE task = $1" - " AND scan_run_status = %u" - " ORDER BY date DESC" - " LIMIT 1 OFFSET 0), $2, $3))" + /* Only look up the severity when the task has a report. Calling + * report_severity with NULL returns NULL as well, but it costs a + * full evaluation of the severity query for every task that never + * ran, which dominates aggregates over many tasks. */ + " (SELECT report_severity (last_report.id, $2, $3)" + " FROM (SELECT id FROM reports" + " WHERE task = $1" + " AND scan_run_status = %u" + " ORDER BY date DESC" + " LIMIT 1 OFFSET 0) AS last_report)" " END;" "$$ LANGUAGE SQL;", TASK_STATUS_DONE);