Я проверил и наш запрос очень медленно тоже.Корень этой проблемы в том, что «таблицы» в information_schema
на самом деле представляют собой сложные представления для предоставления каталогов в соответствии со стандартом SQL.В этом конкретном случае все еще сложнее, поскольку внешние ключи могут быть построены на нескольких столбцах.Ваш запрос дает повторяющихся строк для тех случаев, которые, я подозреваю, могут быть нежелательным побочным эффектом.
Это также причина для конструкции подзапроса с unnest
и ARRAY
в моем запросе ниже.
Пожалуйста, рассмотрите этот альтернативный запрос.Он выдает ту же информацию, просто без повторяющихся строк и в 100 раз быстрее .Кроме того, я рискну гарантировать, без взаимных блокировок.
Конечно, этот запрос работает только для PostgreSQL и не переносим на другие СУБД.
SELECT c.conrelid::regclass AS table_name
,c.conname AS fk_name
,ARRAY(SELECT a.attname
FROM unnest(c.conkey) x
JOIN pg_attribute a
ON a.attrelid = c.conrelid AND a.attnum = x) AS fk_columns
,c.confrelid::regclass AS ref_table
,ARRAY(SELECT a.attname
FROM unnest(c.confkey) x
JOIN pg_attribute a
ON a.attrelid = c.confrelid AND a.attnum = x) AS ref_columns
FROM pg_catalog.pg_constraint c
WHERE c.contype = 'f';
-- ORDER BY c.conrelid::regclass::text,2
Я использую специальную операция литья table_oid::regclass
.который выдает имена таблиц, как видно из вашего текущего активного search_path
.Это может или не может быть то, что вы хотите.Чтобы этот запрос включал абсолютный путь (схему) для каждого имени таблицы, вы можете установить search_path
следующим образом :
SET search_path = pg_catalog;
SELECT ...
Вы, вероятно, знаете остальное, ноЯ включил его для широкой публики.
Если вы продолжите эту сессию и захотите вернуться по умолчанию для search_path, тогда:
RESET search_path;
В случае, если вы должны использовать пользовательский search_path
, выпришлось бы установить его снова.