Sql 如何删除重复索引
我正在寻找一个脚本自动删除重复索引,而不是逐个手动检查和删除表 是否可以通过SQL代码或PL/pgSQL代码删除 脚本正在使用查找重复索引:Sql 如何删除重复索引,sql,postgresql,indexing,Sql,Postgresql,Indexing,我正在寻找一个脚本自动删除重复索引,而不是逐个手动检查和删除表 是否可以通过SQL代码或PL/pgSQL代码删除 脚本正在使用查找重复索引: SELECT indrelid::regclass AS TableName ,array_agg(indexrelid::regclass) AS Indexes FROM pg_index GROUP BY indrelid ,indkey HAVING COUNT(*) > 1; 这是可能的,但似乎不明智
SELECT
indrelid::regclass AS TableName
,array_agg(indexrelid::regclass) AS Indexes
FROM pg_index
GROUP BY
indrelid
,indkey
HAVING COUNT(*) > 1;
这是可能的,但似乎不明智 在
psql
中,您可以使用\gexec运行任意SQL查询/语句,这些查询/语句由另一个查询的结果组成。在pl/pgsql中,您可以使用它来执行希望由其他查询结果组成的任何语句
但是您的查询会将不同的索引标识为重复索引。例如,同一列上的btree索引和gin_trgm_ops索引实际上并不重复,因为它们支持不同的操作,盲目删除一个索引可能是错误的。另外,对于任何表达式,indkey都包含0,因此它会将不同表达式上的表达式索引标识为相同的
因此,虽然您可以在psql
中执行此操作,以删除重复数组中除第一次出现以外的所有内容,但您确实不应该:
select 'drop index '||unnest(indexes[2:]) from (SELECT
indrelid::regclass AS TableName
,array_agg(indexrelid::regclass) AS Indexes
FROM pg_index
GROUP BY
indrelid
,indkey
HAVING COUNT(*) > 1) foo \gexec
在使用regexp剥离索引名称后,可以通过按索引的定义进行分组来优化它,以排除将并非真正重复的索引分组在一起
SELECT
indrelid::regclass AS TableName
,array_agg(indexrelid::regclass) AS Indexes
FROM pg_index
GROUP BY
indrelid
,indkey
,regexp_replace(pg_get_indexdef(pg_index.indexrelid),'^CREATE (UNIQUE )?INDEX (\w+|".+")','')
HAVING COUNT(*) > 1
我不能保证regexp对所有恶意创建的索引名都是安全的。它还将唯一索引和非唯一索引放在一起——可能您实际上想将它们放在一起,但要确保其中一个唯一的索引是幸存的索引。完整地说,您可能还想对IMDISVALID执行一些操作。自动删除数据库对象基本上是个坏主意。这些对象的存在,或者在某个时候是为了某个目的而存在的。对于每个你想放下的物体,你需要问:这个目的是否仍然有效。如果是,那么您是否有其他解决方案?你的建议似乎属于“我想改变数据库,但我不想花时间去理解它”的范畴。看看詹尼斯给出的警告。它会满足你的要求,但会满足你的要求。它们很可能是非常不同的东西。