パーティション分割されたテーブルにインデックスを作成すると、各パーティションは独自のインデックスを取得します。メインインデックスを削除しても、これらは削除されません。
これを行う簡単な方法はありますか?
最上位のインデックス名とパーティションサフィックスが一致するすべてのインデックスを検索する関数を作成しました。この関数は、パーティションで作成されたインデックスに対して正常に機能します。
ただし、Greenplumがデフォルトのパーティション分割によって新しいパーティションを追加すると、まったく異なる命名規則でそのパーティションの新しいインデックスが生成されます。
既存のパーティションには、indexname_1_prt_partitionnameのような名前が付けられます
新しいパーティションにはtablename_1_prt_partitionname_indexcolumnのような名前が付けられます
名前が一致しない場合、新しいパーティションインデックスが親インデックスの一部であることをどのようにして特定できるでしょうか?または、一致する2つの異なるパターンでインデックス削除を2回呼び出すだけですか?
以下のBellのクエリ、またはパーティションインデックスを取得するように調整されたクエリ(ヘッドインデックスを既に削除している場合)を使用します。
SELECT child_index.indexrelid::regclass
FROM pg_index AS partition_index
-- Find the partition that the partition index is on
INNER JOIN pg_partition_rule parindex_rule ON parindex_rule.parchildrelid = partition_index.indrelid
-- Follup up to the partitioning scheme
INNER JOIN pg_partition ON pg_partition.oid = parindex_rule.paroid
-- Follow the links through to the individual partitions
INNER JOIN pg_partition_rule ON pg_partition_rule.paroid = pg_partition.oid
-- Find the indexes on each partition
INNER JOIN pg_index AS child_index ON child_index.indrelid = pg_partition_rule.parchildrelid
-- Which are on the same field as the named index
AND child_index.indkey = partition_index.indkey
-- Using the same comparison operator
AND child_index.indclass = partition_index.indclass
-- Filtered for the index we're trying to drop
WHERE partition_index.indexrelid = 'schema.partitionindexname'::regclass
Greenplumは(バージョン4.3.8のように)パーティションのインデックスをベーステーブルのインデックスにリンクするカタログのレコードを維持しません。最良のオプションは、パーティションを追跡し、基本インデックスの定義と一致するパーティション上のインデックスを見つけることです。
CREATE OR REPLACE FUNCTION drop_child_indexes (index_name varchar)
RETURNS VOID
AS
$functionBody$
DECLARE
child_index_name varchar;
BEGIN
FOR child_index_name IN
SELECT child_index.indexrelid::regclass
FROM pg_index AS parent_index
-- Find the partitioning scheme for the table the index is on
INNER JOIN pg_partition ON pg_partition.parrelid = parent_index.indrelid
-- Follow the links through to the individual partitions
INNER JOIN pg_partition_rule ON pg_partition_rule.paroid = pg_partition.oid
-- Find the indexes on each partition
INNER JOIN pg_index AS child_index ON child_index.indrelid = pg_partition_rule.parchildrelid
-- Which are on the same field as the named index
AND child_index.indkey = parent_index.indkey
-- Using the same comparison operator
AND child_index.indclass = parent_index.indclass
-- Filtered for the index we're trying to drop
WHERE parent_index.indexrelid = $1::regclass::oid
-- Drop leaves first, even if it doesn't really matter in this case
ORDER BY pg_partition.parlevel DESC
LOOP
RAISE NOTICE '%', child_index_name||' ';
EXECUTE 'DROP INDEX '||child_index_name||';';
END LOOP;
END
$functionBody$
LANGUAGE plpgsql;
同じ定義(フィールド、比較演算子)を持つ別のインデックスがある場合、そのパーティションインデックスも削除されます。完全な答えではありませんが、部分文字列のマッチングよりは優れています。
これに対する私の新しい解決策は、新しいパーティションを作成するときにインデックスの名前を変更することです。パーティションの作成はplsqlプロシージャですでに行っているため、プロセスは次のようになります。
このようにして、インデックスは常に一貫した名前を持ち、重複することはありません。つまり、列リストのマッチングではなく、名前のマッチングを使用して子インデックスを削除できます。動作するようになったらコードを投稿します。