Standard PostgreSQL does not support global indexes on partitioned tables. PolarDB for Oracle extends this behavior: when a partitioned table has a global index, DELETE and UPDATE operations use a global index scan to locate rows directly — avoiding a sequential scan across every partition and reducing DML cost on large partitioned tables.
Prerequisites
Before you begin, ensure that you have:
A PolarDB for Oracle cluster
A partitioned table with a global index
Set up a partitioned table with a global index
The following example creates a range-partitioned table, inserts sample data, and adds a global index on column b.
CREATE TABLE gi_ora
(
a int,
b int,
c int GENERATED ALWAYS AS (b * 2),
d int DEFAULT 0,
e int,
f text,
g text
) PARTITION BY RANGE (a)
(
partition p0 values less than (50),
partition p1 values less than (100),
partition p2 values less than (200),
partition p3 values less than (300),
partition p4 values less than (400),
partition p5 values less than (500),
partition p6 values less than (600),
partition p7 values less than (700),
partition p8 values less than (800)
);
INSERT INTO gi_ora(a,b,d,e,f,g)
SELECT i, i, i,
(random()*1000)::int,
(random()*30000000)::int::text,
(random()*30000000)::int::text
FROM generate_series(1,799) i;
CREATE INDEX ON gi_ora(b) global;
ANALYZE gi_ora;The CREATE INDEX ... global statement creates a global index named gi_ora_global_idx that spans all partitions. A global index maintains entries across all partitions, so a single index lookup is enough to find any matching row regardless of which partition it lives in. A local index, by contrast, is scoped to a single partition.
Use global index scan in DELETE
Run EXPLAIN to confirm the planner uses a global index scan for a DELETE filtered on column b:
EXPLAIN (costs off, verbose on) DELETE FROM gi_ora WHERE b = 198;Expected output:
QUERY PLAN
----------------------------------------------------------------------------
DELETE ON global_index_dml.gi_ora
-> GLOBAL INDEX SCAN USING gi_ora_global_idx ON global_index_dml.gi_ora
Output: gi_ora.tableoid, gi_ora.ctid
Index Cond: (gi_ora.b = 198)
(4 rows)The GLOBAL INDEX SCAN USING gi_ora_global_idx line confirms the planner used the global index to locate the target row. Index Cond shows the filter applied at the index level. tableoid and ctid identify the physical location of the matching row so the DELETE can find and remove it without scanning each partition.
To see the impact, compare with a DELETE that filters on a column without a global index. The planner falls back to scanning each partition:
EXPLAIN (costs off, verbose on) DELETE FROM gi_ora WHERE e = 500;Expected output:
QUERY PLAN
-------------------------------------------------------------------------------------
Delete on global_index_dml.gi_ora
-> Append
-> Seq Scan on global_index_dml.gi_ora_p0
Filter: (gi_ora_p0.e = 500)
-> Seq Scan on global_index_dml.gi_ora_p1
Filter: (gi_ora_p1.e = 500)
-> Seq Scan on global_index_dml.gi_ora_p2
Filter: (gi_ora_p2.e = 500)
...
(n rows)The comparison plan above is illustrative. The exact output depends on your table definition and partition count.
Use global index scan in UPDATE
Run EXPLAIN to confirm the planner uses a global index scan for an UPDATE filtered on column b:
EXPLAIN (costs off, verbose on) UPDATE gi_ora SET a = a - 10 WHERE b = 198;Expected output:
QUERY PLAN
----------------------------------------------------------------------------
UPDATE ON global_index_dml.gi_ora
-> GLOBAL INDEX SCAN USING gi_ora_global_idx ON global_index_dml.gi_ora
Output: (gi_ora.a - 10), gi_ora.tableoid, gi_ora.ctid
Index Cond: (gi_ora.b = 198)
(4 rows)The plan structure is the same as for DELETE. The Output line now includes the updated value (gi_ora.a - 10), which is the new value written back to the matched row.
Usage notes
| Topic | Details |
|---|---|
| Supported DML operations | Global index scan applies to DELETE and UPDATE only. It does not apply to INSERT or SELECT. |
| Filter column requirement | The global index must be defined on the filter column. If the WHERE clause filters on a non-indexed column, the planner falls back to a sequential scan across partitions. |
| Partition maintenance | When you drop or truncate a partition, the global index may be marked unusable and must be rebuilt with REINDEX. Factor this into your partition maintenance plan. |