Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何删除重复索引_Sql_Postgresql_Indexing - Fatal编程技术网

Sql 如何删除重复索引

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; 这是可能的,但似乎不明智

我正在寻找一个脚本自动删除重复索引,而不是逐个手动检查和删除表

是否可以通过SQL代码或PL/pgSQL代码删除

脚本正在使用查找重复索引:

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执行一些操作。

自动删除数据库对象基本上是个坏主意。这些对象的存在,或者在某个时候是为了某个目的而存在的。对于每个你想放下的物体,你需要问:这个目的是否仍然有效。如果是,那么您是否有其他解决方案?你的建议似乎属于“我想改变数据库,但我不想花时间去理解它”的范畴。看看詹尼斯给出的警告。它会满足你的要求,但会满足你的要求。它们很可能是非常不同的东西。