From ff553a824fb704ad9f23f86261a50a17c8330348 Mon Sep 17 00:00:00 2001 From: Ralf Wiebicke Date: Fri, 2 Feb 2024 11:41:41 +0100 Subject: [PATCH] MysqlSchemaDialect verifies check constraints without database joins similar to 1a9606ce934d9908ef8e4cc1b169c382efdfaa9c Fri Feb 18 14:54:00 2022 +0100 MysqlSchemaDialect verifies foreign key constraints without database joins --- .../com/exedio/cope/MysqlSchemaDialect.java | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/runtime/mysqlsrc/com/exedio/cope/MysqlSchemaDialect.java b/runtime/mysqlsrc/com/exedio/cope/MysqlSchemaDialect.java index 2ac44182a9..91bca0c4ee 100644 --- a/runtime/mysqlsrc/com/exedio/cope/MysqlSchemaDialect.java +++ b/runtime/mysqlsrc/com/exedio/cope/MysqlSchemaDialect.java @@ -218,27 +218,51 @@ protected void verify(final Schema schema) if(mysql80) // check constraints { + // Querying TABLE_CONSTRAINTS and CHECK_CONSTRAINTS separately is much faster + // than a database join between both tables. + // For an example schema with 17351 check constraints the join did take 21 minutes. + // For the same schema the two separate queries do take just less than a second. + final HashMap tables = new HashMap<>(); + querySQL(schema, + //language=SQL + "SELECT " + + "TABLE_NAME," + // 1 + "CONSTRAINT_NAME " + // 2 + "FROM information_schema.TABLE_CONSTRAINTS " + + "WHERE CONSTRAINT_TYPE='CHECK' " + + "AND CONSTRAINT_TYPE='CHECK' " + + "AND CONSTRAINT_SCHEMA=" + catalog + " " + + "AND TABLE_SCHEMA=" + catalog + " " + + "AND ENFORCED='YES'", + resultSet -> + { + while(resultSet.next()) + { + final Table table = getTableStrict(schema, resultSet, 1); + final String constraintName = resultSet.getString(2); + final Table collision = + tables.putIfAbsent(constraintName, table); + if(collision!=null) + throw new RuntimeException(constraintName + '|' + table); + } + }); querySQL(schema, //language=SQL "SELECT " + - "tc.TABLE_NAME," + // 1 - "cc.CONSTRAINT_NAME," + // 2 - "cc.CHECK_CLAUSE " + // 3 - "FROM information_schema.CHECK_CONSTRAINTS cc " + - "INNER JOIN information_schema.TABLE_CONSTRAINTS tc " + - "ON cc.CONSTRAINT_NAME=tc.CONSTRAINT_NAME " + - "WHERE cc.CONSTRAINT_SCHEMA=" + catalog + " " + - "AND tc.CONSTRAINT_TYPE='CHECK' " + - "AND tc.CONSTRAINT_SCHEMA=" + catalog + " " + - "AND tc.TABLE_SCHEMA=" + catalog + " " + - "AND tc.ENFORCED='YES'", + "CONSTRAINT_NAME," + // 1 + "CHECK_CLAUSE " + // 2 + "FROM information_schema.CHECK_CONSTRAINTS " + + "WHERE CONSTRAINT_SCHEMA=" + catalog, resultSet -> { while(resultSet.next()) { - final Table table = getTableStrict(schema, resultSet, 1); - final String constraintName = resultSet.getString(2); - final String clause = strip(resultSet.getString(3), "(", ")"); + final String constraintName = resultSet.getString(1); + final String clause = strip(resultSet.getString(2), "(", ")"); + final Table table = tables.get(constraintName); + if(table==null) // happens for non-ENFORCED check constraints + continue; + //System.out.println("tableName:"+table+" constraintName:"+constraintName+" clause:>"+clause+"<"); notifyExistentCheck(table, constraintName, clause); }