[英]I need to optimise the following pgsql select statement - its currently taking 34 avg seconds to execute
I have a view that shows all relations.我有一个显示所有关系的视图。
I use the following select for the view:我使用以下 select 作为视图:
CREATE VIEW relationships AS SELECT DISTINCT
relations.name,
sch_tco.id AS table_id,
relations.related_table AS related_table,
scd_tco.id AS related_id,
relations.foreign_column AS foreign_column_name,
relations.local_column AS local_column_name,
count(DISTINCT relations.name) AS relationships,
count(DISTINCT relations.referenced_tables) AS foreign_keys_count,
count(DISTINCT relations.referencing_tables) AS references_count,
count(DISTINCT related_table) AS related_tables_count,
count(DISTINCT relations.referenced_tables) AS referenced_tables_count,
count(DISTINCT relations.referencing_tables) AS referencing_tables_count
FROM ( SELECT DISTINCT
pk_tco.table_name AS name,
fk_tco.table_name AS related_table,
fk_tco.table_name AS referencing_tables,
NULL::varchar(100) AS referenced_tables,
cc_tco.column_name AS foreign_column,
pc_tco.column_name AS local_column
FROM
information_schema.referential_constraints rco
JOIN information_schema.table_constraints fk_tco ON rco.constraint_name = fk_tco.constraint_name
AND rco.constraint_schema = fk_tco.table_schema
JOIN information_schema.table_constraints pk_tco ON rco.unique_constraint_name = pk_tco.constraint_name
AND rco.unique_constraint_schema = pk_tco.table_schema
JOIN information_schema.constraint_column_usage AS cc_tco ON cc_tco.constraint_name = pk_tco.constraint_name
AND cc_tco.table_schema = pk_tco.table_schema
JOIN information_schema.key_column_usage AS kc_tco ON kc_tco.constraint_name = pk_tco.constraint_name
AND kc_tco.table_schema = pk_tco.table_schema
JOIN information_schema.key_column_usage AS pc_tco ON pc_tco.constraint_name = fk_tco.constraint_name
AND pc_tco.table_schema = fk_tco.table_schema
GROUP BY
name,
related_table,
referenced_tables,
referencing_tables,
foreign_column,
local_column
UNION ALL SELECT DISTINCT
fk_tco.table_name AS name,
pk_tco.table_name AS related_table,
NULL AS referencing_tables,
pk_tco.table_name AS referenced_tables,
kc_tco.column_name AS foreign_column,
pc_tco.column_name AS local_column
FROM
information_schema.referential_constraints rco
JOIN information_schema.table_constraints fk_tco ON rco.constraint_name = fk_tco.constraint_name
AND rco.constraint_schema = fk_tco.table_schema
JOIN information_schema.table_constraints pk_tco ON rco.unique_constraint_name = pk_tco.constraint_name
AND rco.unique_constraint_schema = pk_tco.table_schema
JOIN information_schema.columns p ON fk_tco.table_name = p.table_name
JOIN information_schema.columns t ON pk_tco.table_name = t.table_name
JOIN information_schema.constraint_column_usage AS cc_tco ON cc_tco.constraint_name = fk_tco.constraint_name
AND cc_tco.table_schema = fk_tco.table_schema
JOIN information_schema.key_column_usage AS kc_tco ON kc_tco.constraint_name = pk_tco.constraint_name
AND kc_tco.table_schema = pk_tco.table_schema
AND kc_tco.position_in_unique_constraint = kc_tco.ordinal_position --IMPORTANT!
JOIN information_schema.key_column_usage AS pc_tco ON pc_tco.constraint_name = fk_tco.constraint_name
AND pc_tco.table_schema = fk_tco.table_schema
AND pc_tco.position_in_unique_constraint = pc_tco.ordinal_position --IMPORTANT!
GROUP BY
name,
related_table,
referencing_tables,
referenced_tables,
foreign_column,
local_column) relations
JOIN tables sch_tco ON relations.name = sch_tco.name
JOIN tables scd_tco ON relations.related_table = scd_tco.name
JOIN information_schema.columns t ON sch_tco.name = t.table_name
JOIN information_schema.columns p ON scd_tco.name = p.table_name
GROUP BY
relations.name,
related_table,
table_id,
related_id,
foreign_column_name,
local_column_name
ORDER BY
relationships DESC;
It produces a table as follows它产生一个表如下
name![]() |
table_id![]() |
related_table![]() |
related_id ![]() |
foreign_column_name ![]() |
local_column_name ![]() |
relationships![]() |
foreign_keys_count ![]() |
references_count![]() |
related_tables_count ![]() |
referenced_tables_count ![]() |
referencing_tables_count ![]() |
---|---|---|---|---|---|---|---|---|---|---|---|
users![]() |
8298968d-54c9-496a-8320-bb67ffb5cfec ![]() |
configs![]() |
f954e6b8-111c-4ed7-b6d6-d68545640645 ![]() |
id ![]() |
user_id![]() |
1 ![]() |
0 ![]() |
1 ![]() |
1 ![]() |
0 ![]() |
1 ![]() |
users![]() |
8298968d-54c9-496a-8320-bb67ffb5cfec ![]() |
todos![]() |
d1de713a-5405-4bc6-80be-5c4c20d0343c ![]() |
id ![]() |
user_id![]() |
1 ![]() |
0 ![]() |
1 ![]() |
1 ![]() |
0 ![]() |
1 ![]() |
And then I use the following select to join tables table with the relations.然后我使用以下 select 将表与关系连接起来。 with the following select.
与以下 select。
select tables.id id,
tables.name name,
tables.parent parent,
(select jsonb_agg(relationships.*)
from relationships
where exists(select * from relationships where relationships.table_id = tables.id)) relations,
(select distinct jsonb_agg(jsonb_build_object('name', cols.column_name, 'type', cols.udt_name))
from information_schema.columns cols
where cols.table_name = tables.name) table_schema
from tables tables
join relationships on relationships.table_id = tables.id
join information_schema.columns table_cols on tables.name = table_cols.table_name
UNION
select tables.id id,
tables.name name,
tables.parent parent,
(select jsonb_agg(relationships.*)
from relationships
where exists(select * from relationships where relationships.table_id = tables.id)) relations,
(select distinct jsonb_agg(jsonb_build_object('name', cols.column_name, 'type', cols.udt_name))
from information_schema.columns cols
where cols.table_name = tables.name) table_schema
from tables tables
join information_schema.columns cols on tables.name = cols.table_name
This returns the correct data only it takes 35 seconds on average.这只返回正确的数据,平均只需要 35 秒。 I think its because I'm joining similar tables but I cant be certain.
我认为这是因为我加入了类似的表格,但我不能确定。
I solved it with this query:我用这个查询解决了它:
select distinct tables.id,
tables.name,
tables.parent,
(SELECT jsonb_agg(jsonb_build_object(
'table_schema', tc.table_schema,
'constraint_name', tc.constraint_name,
'table_name', tc.table_name,
'column_name', kcu.column_name,
'foreign_table_schema', ccu.table_schema,
'foreign_table_name', ccu.table_name,
'foreign_column_name', ccu.column_name))
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
AND ccu.table_schema = tc.table_schema
WHERE tc.constraint_type = 'FOREIGN KEY' and ccu.table_name = tables.name) relationships,
(select jsonb_agg(jsonb_build_object('name', cols.column_name, 'type', cols.udt_name))
from information_schema.columns cols
where cols.table_name = tables.name) table_schema
from tables
left join information_schema.columns table_cols on tables.name = table_cols.table_name
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.