big*_*mus 15 sql database postgresql indexing foreign-keys
我正在使用大型PostgreSQL数据库,我正在尝试调整它以获得更高的性能.
我们的查询和更新似乎使用外键进行了大量查找.
我想要的是一种相对简单的方法,可以将索引添加到我们的所有外键,而无需遍历每个表(~140)并手动执行.
在研究这个时,我发现没有办法让Postgres自动为你做这件事(就像MySQL那样),但我也很乐意听到其他的说法.
ara*_*nid 18
编辑:所以,我写下面的查询,然后认为......"坚持,Postgresql要求外键目标必须有唯一的索引." 所以我想我误解了你的意思?您可以使用下面的查询,以检查源的外键具有指数由substituing为"confrelid"和"康基"为"confkey"(是啊,是啊,在查询中没有别名...)"conrelid"
嗯,我想它应该有可能要经过系统目录...像往常一样,到系统目录最好的指南是使用psql的,做"\设置ECHO_HIDDEN 1",然后看看它会产生有趣的是什么SQL"\ d"命令.这是用于查找表的外键的SQL("\ d tablename"):
-- $1 is the table OID, e.g. 'tablename'::regclass
SELECT conname, conrelid::pg_catalog.regclass,
pg_catalog.pg_get_constraintdef(c.oid, true) as condef
FROM pg_catalog.pg_constraint c
WHERE c.confrelid = $1 AND c.contype = 'f' ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)
似乎pg_constraint具有列conkey和confkey看起来像他们可能是关键跨定义的列数.可能confkey是外表中的列号,因为它只对外键非空.另外,花了一段时间才意识到这是显示引用给定表的外键的SQL .无论如何,这是我们想要的.
所以这个查询显示数据开始成形:
select confrelid, conname, column_index, attname
from pg_attribute
join (select confrelid::regclass, conname, unnest(confkey) as column_index
from pg_constraint
where confrelid = 'ticket_status'::regclass) fkey
on fkey.confrelid = pg_attribute.attrelid
and fkey.column_index = pg_attribute.attnum
Run Code Online (Sandbox Code Playgroud)
我将会使用像undest这样的8.4功能......你可以在没有的情况下相处.
我结束了:
select pg_index.indexrelid::regclass, 'create index ' || relname || '_' ||
array_to_string(column_name_list, '_') || '_idx on ' || confrelid ||
' (' || array_to_string(column_name_list, ',') || ')'
from (select distinct
confrelid,
array_agg(attname) column_name_list,
array_agg(attnum) as column_list
from pg_attribute
join (select confrelid::regclass,
conname,
unnest(confkey) as column_index
from (select distinct
confrelid, conname, confkey
from pg_constraint
join pg_class on pg_class.oid = pg_constraint.confrelid
join pg_namespace on pg_namespace.oid = pg_class.relnamespace
where nspname !~ '^pg_' and nspname <> 'information_schema'
) fkey
) fkey
on fkey.confrelid = pg_attribute.attrelid
and fkey.column_index = pg_attribute.attnum
group by confrelid, conname
) candidate_index
join pg_class on pg_class.oid = candidate_index.confrelid
left join pg_index on pg_index.indrelid = confrelid
and indkey::text = array_to_string(column_list, ' ')
Run Code Online (Sandbox Code Playgroud)
好吧,这个怪物打印出候选索引命令,并尝试将它们与现有索引相匹配.因此,您可以在末尾添加"where indexrelid为null",以获取创建似乎不存在的索引的命令.
此查询不能很好地处理多列外键; 但是,如果你使用那些,你应该得到麻烦.
LATER EDIT:这是在顶部放置的建议编辑的查询.所以这显示了创建不存在的索引的命令,在作为外键源(而不是其目标)的列上.
select pg_index.indexrelid::regclass, 'create index ' || relname || '_' ||
array_to_string(column_name_list, '_') || '_idx on ' || conrelid ||
' (' || array_to_string(column_name_list, ',') || ')'
from (select distinct
conrelid,
array_agg(attname) column_name_list,
array_agg(attnum) as column_list
from pg_attribute
join (select conrelid::regclass,
conname,
unnest(conkey) as column_index
from (select distinct
conrelid, conname, conkey
from pg_constraint
join pg_class on pg_class.oid = pg_constraint.conrelid
join pg_namespace on pg_namespace.oid = pg_class.relnamespace
where nspname !~ '^pg_' and nspname <> 'information_schema'
) fkey
) fkey
on fkey.conrelid = pg_attribute.attrelid
and fkey.column_index = pg_attribute.attnum
group by conrelid, conname
) candidate_index
join pg_class on pg_class.oid = candidate_index.conrelid
left join pg_index on pg_index.indrelid = conrelid
and indkey::text = array_to_string(column_list, ' ')
where indexrelid is null
Run Code Online (Sandbox Code Playgroud)
我的经验是,这并不是真的有用.它建议为参考代码创建索引,这些参考代码实际上不需要编制索引.
信息位于目录表中.但似乎并不是非常直接的想要你需要,特别是如果已经创建了一些索引(以及多列索引......)
如果你没有任何索引的FK,你可以做一些快速而又脏的事情
SELECT 'CREATE INDEX ' || table_name || '_' || column_name || '_idx ON '
|| table_name || '(' || column_name || ');'
from foreign_key_tables where schema = 'public';
Run Code Online (Sandbox Code Playgroud)
您将替换为您感兴趣的架构,将其转储到文件,编辑,检查,祈祷并提供给psql.请注意,此过程不会检测已存在的索引.
啊,foreign_key_tables是一个信息视图创建为:
CREATE VIEW foreign_key_tables AS SELECT
n.nspname AS schema,
cl.relname AS table_name,
a.attname AS column_name,
ct.conname AS key_name,
nf.nspname AS foreign_schema,
clf.relname AS foreign_table_name,
af.attname AS foreign_column_name,
pg_get_constraintdef(ct.oid) AS create_sql
FROM pg_catalog.pg_attribute a
JOIN pg_catalog.pg_class cl ON (a.attrelid = cl.oid AND cl.relkind =
'r')
JOIN pg_catalog.pg_namespace n ON (n.oid = cl.relnamespace)
JOIN pg_catalog.pg_constraint ct ON (a.attrelid = ct.conrelid AND
ct.confrelid != 0 AND ct.conkey[1] = a.attnum)
JOIN pg_catalog.pg_class clf ON (ct.confrelid = clf.oid AND clf.relkind
= 'r')
JOIN pg_catalog.pg_namespace nf ON (nf.oid = clf.relnamespace)
JOIN pg_catalog.pg_attribute af ON (af.attrelid = ct.confrelid AND
af.attnum = ct.confkey[1]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7721 次 |
| 最近记录: |