diff --git a/src/main/resources/db/liquibase/qbit-alerts/alerts.changelog.sql b/src/main/resources/db/liquibase/qbit-alerts/alerts.changelog.sql index f17b9cf..cc79de1 100644 --- a/src/main/resources/db/liquibase/qbit-alerts/alerts.changelog.sql +++ b/src/main/resources/db/liquibase/qbit-alerts/alerts.changelog.sql @@ -519,3 +519,9 @@ CREATE INDEX ix_alerts_notification_recipient_slack_status ON alerts_notificatio -- precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.columns WHERE LOWER(table_name) = 'alerts_notification_preference' AND LOWER(column_name) = 'in_app_min_severity' -- comment: Optional minimum severity for in-app notifications (security always arrives). ALTER TABLE alerts_notification_preference ADD COLUMN in_app_min_severity VARCHAR(16); + +-- changeset qbit-alerts:30 +-- comment: Indexes for the join child columns: a per-record monitor finds its open alerts by (monitor_id, status) on every evaluation (MonitorEvaluator), and the record pages list a type's monitors (alert_type_id) and a group's types (group_id). +CREATE INDEX IF NOT EXISTS ix_alerts_alert_monitor_id_status ON alerts_alert (monitor_id, status); +CREATE INDEX IF NOT EXISTS ix_alerts_monitor_alert_type_id ON alerts_monitor (alert_type_id); +CREATE INDEX IF NOT EXISTS ix_alerts_type_group_id ON alerts_type (group_id); diff --git a/src/test/java/com/kingsrook/qbits/alerts/AlertsQBitProducerTest.java b/src/test/java/com/kingsrook/qbits/alerts/AlertsQBitProducerTest.java index e89296a..dcb5eaf 100644 --- a/src/test/java/com/kingsrook/qbits/alerts/AlertsQBitProducerTest.java +++ b/src/test/java/com/kingsrook/qbits/alerts/AlertsQBitProducerTest.java @@ -413,4 +413,35 @@ class AlertsQBitProducerTest extends BaseAlertsTest com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType.INSERT)).isTrue(); } + + + /******************************************************************************* + ** Every one-to-many join's child column leads an index in the shipped + ** changelog, so record pages, child lists and per-parent lookups do not scan + ** the child table. + *******************************************************************************/ + @Test + void testJoinChildColumnsAreIndexed() throws Exception + { + String changelog; + try(InputStream in = getClass().getClassLoader().getResourceAsStream("db/liquibase/qbit-alerts/alerts.changelog.sql")) + { + changelog = new String(in.readAllBytes(), StandardCharsets.UTF_8); + } + for(com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData join : AlertsTableMetaDataHelper.buildJoins()) + { + String table = join.getRightTable(); + String column = join.getJoinOns().get(0).getRightField().replaceAll("([a-z0-9])([A-Z])", "$1_$2").toLowerCase(); + java.util.regex.Pattern index = java.util.regex.Pattern.compile("(?i)CREATE (UNIQUE )?INDEX (IF NOT EXISTS )?\\w+ ON " + table + " \\(" + column + "[,)]"); + java.util.regex.Pattern unique = java.util.regex.Pattern.compile("(?is)CREATE TABLE IF NOT EXISTS " + table + " \\((?:(?!\\);).)*UNIQUE \\(" + column + "[,)]"); + ////////////////////////////////////////////////////////////////////// + // alerts_delivery was renamed from the RC.1 alerts_notification; // + // its indexes came along by ALTER INDEX ... RENAME TO ix__ // + ////////////////////////////////////////////////////////////////////// + boolean renamed = changelog.contains("RENAME TO ix_" + table + "_" + column + ";") || changelog.contains("RENAME TO ix_" + table + "_" + column + "_"); + assertThat(index.matcher(changelog).find() || unique.matcher(changelog).find() || renamed) + .as("index leading with " + table + "." + column + " for join " + join.getName()) + .isTrue(); + } + } }