问题描述
SELECT
`RC` . `CONSTRAINT_CATALOG` AS `fkCatalog`,`RC` . `CONSTRAINT_SCHEMA` AS `fkSchema`,`RC` . `CONSTRAINT_NAME` AS `fkName`,`RC` . `UPDATE_RULE` AS `onUpdate`,`RC` . `DELETE_RULE` AS `onDelete`,`RC` . `TABLE_NAME` AS `fkTable`,`RC` . `REFERENCED_TABLE_NAME` AS `refTable`,`KCU` . `COLUMN_NAME` AS `fkColumn`,`KCU` . `REFERENCED_COLUMN_NAME` AS `refColumn`,`KCU` . `ORDINAL_POSITION` AS `fkOrdinal`
FROM
`informatION_SCHEMA` . `referential_CONSTRAINTS` AS `RC`
INNER JOIN `informatION_SCHEMA` . `KEY_COLUMN_USAGE` AS `KCU`
ON
`KCU` . `CONSTRAINT_SCHEMA` = `RC` . `CONSTRAINT_SCHEMA` AND
`KCU` . `CONSTRAINT_NAME` = `RC` . `CONSTRAINT_NAME`
WHERE
`RC` . `CONSTRAINT_SCHEMA` = ? AND
`RC` . `TABLE_NAME` = ?
ORDER BY
`RC` . `REFERENCED_TABLE_NAME`,`KCU` . `ORDINAL_POSITION`
例如查看答案:
https://dba.stackexchange.com/questions/102371/how-to-check-foreign-keys-related-to-a-table
但是在中等大小的数据库(总大小约为20GB,在约20个数据库之间有1000-10000个表)中,这可能要花费几秒钟的时间(在我的系统上,每个查询将近3秒)。
是否有更有效的方式来获取它们?
注意:我正在使用MysqL 5.7。
解决方法
一种解决方案最终是在联接的两侧显式引用表和架构。我知道information_schema表(尤其是在MySQL
我首先尝试颠倒连接顺序,这无济于事,或者将where放在key_column_usage表上,这无济于事。显式引用联接两侧的模式和表确实可以解决问题。
无论如何,以下查询平均花费1-2毫秒,而上面的查询平均花费不到3秒(从Performance_schema的1000多个查询中提取的数字)。
SELECT
`RC` . `CONSTRAINT_CATALOG` AS `fkCatalog`,`RC` . `CONSTRAINT_SCHEMA` AS `fkSchema`,`RC` . `CONSTRAINT_NAME` AS `fkName`,`RC` . `UPDATE_RULE` AS `onUpdate`,`RC` . `DELETE_RULE` AS `onDelete`,`RC` . `TABLE_NAME` AS `fkTable`,`RC` . `REFERENCED_TABLE_NAME` AS `refTable`,`KCU` . `COLUMN_NAME` AS `fkColumn`,`KCU` . `REFERENCED_COLUMN_NAME` AS `refColumn`,`KCU` . `ORDINAL_POSITION` AS `fkOrdinal`
FROM
`INFORMATION_SCHEMA` . `KEY_COLUMN_USAGE` AS `KCU`
INNER JOIN
`INFORMATION_SCHEMA` . `REFERENTIAL_CONSTRAINTS` AS `RC`
ON
`KCU` . `CONSTRAINT_SCHEMA` = `RC` . `CONSTRAINT_SCHEMA` AND
`KCU` . `CONSTRAINT_NAME` = `RC` . `CONSTRAINT_NAME`
WHERE
`KCU` . `TABLE_SCHEMA` = ? AND -- The addition of this and the next row are the only real difference.
`KCU` . `TABLE_NAME` = ? AND
`RC` . `CONSTRAINT_SCHEMA` = ? AND
`RC` . `TABLE_NAME` = ?
ORDER BY
`KCU` . `REFERENCED_TABLE_NAME`,`KCU` . `ORDINAL_POSITION`
,
这将为您提供有关外键的所有信息
还有更多信息,例如参考列和刷新表
SELECT
TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL;
此外,在mysql 5.7中有此选项,但仅适用于innodb表
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN
哪个给你类型
TYPE包含有关外键列信息的位标志的集合,或在一起。 1 = ON DELETE CASCADE,2 = ON UPDATE SET NULL,4 = ON UPDATE CASCADE,8 = ON UPDATE SET NULL,16 = ON DELETE NO ACTION,32 = ON UPDATE NO ACTION。