Wednesday, April 5, 2023

Part 2: Steps to move data from a non partitioned table to partitioned table in postgresql

Objective: Steps to move a non-partition table to partition table with indexes

This is a multipart series and in this part, we are going to draft the steps involved in converting a non-partitioned table to partitioned table with indexes.

A) Table Setup:

create table test_nofk as
with t as
(
select generate_series(0,100) lvl
)
select t.lvl
,(mod(t.lvl,100)+date '1/1/2022') as dob
,lpad('A',(mod(t.lvl,20)+(20-mod(t.lvl,20))),chr(65+mod((t.lvl/26),26))) as hosptl
,substr(md5(random()::text),15) as fn
,substr(md5(random()::text),15) as ln
,'UKCO'||chr(65+mod(t.lvl,26))||chr(65+mod((t.lvl/26),26)) as POSCODE
from t;

create index test_nofk_lvl_idx on test_nofk(lvl);

analyze verbose test_nofk;


Table creation output:

postgres=# create table test_nofk as
postgres-# with t as
postgres-# (
postgres(# select generate_series(0,100) lvl
postgres(# )
postgres-# select t.lvl
postgres-# ,(mod(t.lvl,100)+date '1/1/2022') as dob
postgres-# ,lpad('A',(mod(t.lvl,20)+(20-mod(t.lvl,20))),chr(65+mod((t.lvl/26),26))) as hosptl
postgres-# ,substr(md5(random()::text),15) as fn
postgres-# ,substr(md5(random()::text),15) as ln
postgres-# ,'UKCO'||chr(65+mod(t.lvl,26))||chr(65+mod((t.lvl/26),26)) as POSCODE
postgres-# from t;
SELECT 101
postgres=#

postgres=# create index test_nofk_lvl_idx on test_nofk(lvl);
CREATE INDEX
postgres=#

postgres=#
postgres=# analyze verbose test_nofk;
INFO:  analyzing "public.test_nofk"
INFO:  "test_nofk": scanned 2 of 2 pages, containing 101 live rows and 0 dead rows; 101 rows in sample, 101 estimated total rows
ANALYZE
postgres=#
postgres=#

postgres=# \d+ test_nofk
                                         Table "public.test_nofk"
 Column  |  Type   | Collation | Nullable | Default | Storage  | Compression | Stats target | Description
---------+---------+-----------+----------+---------+----------+-------------+--------------+-------------
 lvl     | integer |           |          |         | plain    |             |              |
 dob     | date    |           |          |         | plain    |             |              |
 hosptl  | text    |           |          |         | extended |             |              |
 fn      | text    |           |          |         | extended |             |              |
 ln      | text    |           |          |         | extended |             |              |
 poscode | text    |           |          |         | extended |             |              |
Indexes:
    "test_nofk_lvl_idx" btree (lvl)
Access method: heap
postgres=#


B) In part 1 we already identified the partkey column, so let us proceed with hosptl as part key column.


C) Let us collect dependency diagram (ER), even now we dont have any tables dependent on this table.So let us move forward.

D) Let us get the ddl of the table dumped using pg_dump.

/usr/pgsql-14/bin/pg_dump --table='public.test_nofk' --username=postgres --dbname=postgres --schema-only --file=/tmp/test_nofk_05apr23.sql --verbose

-bash-4.2$ /usr/pgsql-14/bin/pg_dump --table='public.test_nofk' --username=postgres --dbname=postgres --schema-only --file=/tmp/test_nofk_05apr23.sql --verbose
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
...
pg_dump: saving search_path =
pg_dump: creating TABLE "public.test_nofk"
pg_dump: creating INDEX "public.test_nofk_lvl_idx"
-bash-4.2$
Table DDL extracted:
--
-- TOC entry 238 (class 1259 OID 16689)
-- Name: test_nofk; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.test_nofk (
    lvl integer,
    dob date,
    hosptl text,
    fn text,
    ln text,
    poscode text
);

ALTER TABLE public.test_nofk OWNER TO postgres;
--
-- TOC entry 3982 (class 1259 OID 16694)
-- Name: test_nofk_lvl_idx; Type: INDEX; Schema: public; Owner: postgres
--
CREATE INDEX test_nofk_lvl_idx ON public.test_nofk USING btree (lvl);

-- Completed on 2023-04-05 10:30:38 BST
E) Let us get the DDL modified to partition the table on hosptl column (this is no different from part 1)
CREATE TABLE public.test_part_nofk (
    lvl integer,
    dob date,
    hosptl text,
    fn text,
    ln text,
    poscode text
) partition by list(hosptl);
CREATE TABLE public.test_part_nofk_a partition of public.test_part_nofk for values in ('AAAAAAAAAAAAAAAAAAAA');
CREATE TABLE public.test_part_nofk_b partition of public.test_part_nofk for values in ('BBBBBBBBBBBBBBBBBBBA');
CREATE TABLE public.test_part_nofk_c partition of public.test_part_nofk for values in ('CCCCCCCCCCCCCCCCCCCA');
CREATE TABLE public.test_part_nofk_d partition of public.test_part_nofk for values in ('DDDDDDDDDDDDDDDDDDDA');
CREATE TABLE public.test_part_nofk_default partition of public.test_part_nofk default;

postgres=# \d+
                                                        List of relations
 Schema |              Name               |       Type        |  Owner   | Persistence | Access method |    Size    | Desc
ription
--------+---------------------------------+-------------------+----------+-------------+---------------+------------+-----
--------
 public | pg_stat_statements              | view              | postgres | permanent   |               | 0 bytes    |
 public | pg_stat_statements_info         | view              | postgres | permanent   |               | 0 bytes    |
 public | test_nofk                       | table             | postgres | permanent   | heap          | 24 kB      |
..
 public | test_part_nofk                  | partitioned table | postgres | permanent   |               | 0 bytes    |
 public | test_part_nofk_a                | table             | postgres | permanent   | heap          | 8192 bytes |
 public | test_part_nofk_b                | table             | postgres | permanent   | heap          | 8192 bytes |
 public | test_part_nofk_c                | table             | postgres | permanent   | heap          | 8192 bytes |
 public | test_part_nofk_d                | table             | postgres | permanent   | heap          | 8192 bytes |

postgres=# \dt+ test_part_nofk
                                              List of relations
 Schema |      Name      |       Type        |  Owner   | Persistence | Access method |  Size   | Description
--------+----------------+-------------------+----------+-------------+---------------+---------+-------------
 public | test_part_nofk | partitioned table | postgres | permanent   |               | 0 bytes |
(1 row)
postgres=# \d+ test_part_nofk
                                Partitioned table "public.test_part_nofk"
 Column  |  Type   | Collation | Nullable | Default | Storage  | Compression | Stats target | Description
---------+---------+-----------+----------+---------+----------+-------------+--------------+-------------
 lvl     | integer |           |          |         | plain    |             |              |
 dob     | date    |           |          |         | plain    |             |              |
 hosptl  | text    |           |          |         | extended |             |              |
 fn      | text    |           |          |         | extended |             |              |
 ln      | text    |           |          |         | extended |             |              |
 poscode | text    |           |          |         | extended |             |              |
Partition key: LIST (hosptl)
Partitions: test_part_nofk_a FOR VALUES IN ('AAAAAAAAAAAAAAAAAAAA'),
            test_part_nofk_b FOR VALUES IN ('BBBBBBBBBBBBBBBBBBBA'),
            test_part_nofk_c FOR VALUES IN ('CCCCCCCCCCCCCCCCCCCA'),
            test_part_nofk_d FOR VALUES IN ('DDDDDDDDDDDDDDDDDDDA'),
            test_part_nofk_default DEFAULT

F) Let us use COPY method to copy the data from existing table to the new table.

copy test_nofk to '/tmp/test_nofk_05apr23.dmp';
copy test_part_nofk from '/tmp/test_nofk_05apr23.dmp';
analyze verbose test_part_nofk;

Output:
postgres=# copy test_nofk to '/tmp/test_nofk_05apr23.dmp';
COPY 101
postgres=# copy test_part_nofk from '/tmp/test_nofk_05apr23.dmp';
COPY 101
postgres=#

postgres=# analyze verbose test_part_nofk;
INFO:  analyzing "public.test_part_nofk" inheritance tree
INFO:  "test_part_nofk_a": scanned 1 of 1 pages, containing 26 live rows and 0 dead rows; 26 rows in sample, 26 estimated total rows
INFO:  "test_part_nofk_b": scanned 1 of 1 pages, containing 26 live rows and 0 dead rows; 26 rows in sample, 26 estimated total rows
INFO:  "test_part_nofk_c": scanned 1 of 1 pages, containing 26 live rows and 0 dead rows; 26 rows in sample, 26 estimated total rows
INFO:  "test_part_nofk_d": scanned 1 of 1 pages, containing 23 live rows and 0 dead rows; 23 rows in sample, 23 estimated total rows
INFO:  analyzing "public.test_part_nofk_a"
INFO:  "test_part_nofk_a": scanned 1 of 1 pages, containing 26 live rows and 0 dead rows; 26 rows in sample, 26 estimated total rows
INFO:  analyzing "public.test_part_nofk_b"
INFO:  "test_part_nofk_b": scanned 1 of 1 pages, containing 26 live rows and 0 dead rows; 26 rows in sample, 26 estimated total rows
INFO:  analyzing "public.test_part_nofk_c"
INFO:  "test_part_nofk_c": scanned 1 of 1 pages, containing 26 live rows and 0 dead rows; 26 rows in sample, 26 estimated total rows
INFO:  analyzing "public.test_part_nofk_d"
INFO:  "test_part_nofk_d": scanned 1 of 1 pages, containing 23 live rows and 0 dead rows; 23 rows in sample, 23 estimated total rows
INFO:  analyzing "public.test_part_nofk_default"
INFO:  "test_part_nofk_default": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in sample, 0 estimated total rows
ANALYZE
postgres=#

Post load:
postgres=# select relname,relpages,reltuples,relallvisible,relispartition from pg_class where relname like 'test_part_nofk%' order by 1;
        relname         | relpages | reltuples | relallvisible | relispartition
------------------------+----------+-----------+---------------+----------------
 test_part_nofk         |       -1 |       101 |             0 | f
 test_part_nofk_a       |        1 |        26 |             0 | t
 test_part_nofk_b       |        1 |        26 |             0 | t
 test_part_nofk_c       |        1 |        26 |             0 | t
 test_part_nofk_d       |        1 |        23 |             0 | t
 test_part_nofk_default |        0 |         0 |             0 | t
(6 rows)
postgres=#

postgres=# select relname,seq_scan,seq_tup_read,n_tup_ins,n_tup_upd,n_tup_del,n_live_tup,n_mod_since_analyze from pg_stat_user_Tables where relname like 'test_part_nofk%' order by 1;
        relname         | seq_scan | seq_tup_read | n_tup_ins | n_tup_upd | n_tup_del | n_live_tup | n_mod_since_analyze
------------------------+----------+--------------+-----------+-----------+-----------+------------+---------------------
 test_part_nofk         |        0 |            0 |         0 |         0 |         0 |          0 |                   0
 test_part_nofk_a       |        0 |            0 |        26 |         0 |         0 |         26 |                   0
 test_part_nofk_b       |        0 |            0 |        26 |         0 |         0 |         26 |                   0
 test_part_nofk_c       |        0 |            0 |        26 |         0 |         0 |         26 |                   0
 test_part_nofk_d       |        0 |            0 |        23 |         0 |         0 |         23 |                   0
 test_part_nofk_default |        0 |            0 |         0 |         0 |         0 |          0 |                   0
(6 rows)
postgres=#
postgres=#

G) Let us create the index.
We have 2 choices...
1. Create ONLY index and take care of adding index partition manually each time; this doesnt require exclusive lock on the table
2. Create a normal index and the partition scheme is applied automatically.

create index test_part_nofk_lvl_idx ON public.test_part_nofk USING btree (lvl);

Output:
postgres=# create index test_part_nofk_lvl_idx ON public.test_part_nofk USING btree (lvl);
CREATE INDEX
postgres=#

postgres=# select relname,relpages,reltuples,relallvisible,relispartition from pg_class where relname like 'test_part_nofk%' order by 1;
            relname             | relpages | reltuples | relallvisible | relispartition
--------------------------------+----------+-----------+---------------+----------------
 test_part_nofk                 |       -1 |       101 |             0 | f
 test_part_nofk_a               |        1 |        26 |             0 | t
 test_part_nofk_a_lvl_idx       |        2 |        26 |             0 | t <<< notice index already has stats
 test_part_nofk_b               |        1 |        26 |             0 | t
 test_part_nofk_b_lvl_idx       |        2 |        26 |             0 | t
 test_part_nofk_c               |        1 |        26 |             0 | t
 test_part_nofk_c_lvl_idx       |        2 |        26 |             0 | t
 test_part_nofk_d               |        1 |        23 |             0 | t
 test_part_nofk_d_lvl_idx       |        2 |        23 |             0 | t
 test_part_nofk_default         |        0 |         0 |             0 | t
 test_part_nofk_default_lvl_idx |        1 |         0 |             0 | t
 test_part_nofk_lvl_idx         |        0 |         0 |             0 | f
(12 rows)
postgres=#

postgres=# select * from pg_indexes where tablename like 'test_part_nofk%' order by 1,2;
 schemaname |       tablename        |           indexname            | tablespace |                                            indexdef
------------+------------------------+--------------------------------+------------+------------------------------------------------------------------------------------------------
 public     | test_part_nofk         | test_part_nofk_lvl_idx         |            | CREATE INDEX test_part_nofk_lvl_idx ON ONLY public.test_part_nofk USING btree (lvl)
 public     | test_part_nofk_a       | test_part_nofk_a_lvl_idx       |            | CREATE INDEX test_part_nofk_a_lvl_idx ON public.test_part_nofk_a USING btree (lvl)
 public     | test_part_nofk_b       | test_part_nofk_b_lvl_idx       |            | CREATE INDEX test_part_nofk_b_lvl_idx ON public.test_part_nofk_b USING btree (lvl)
 public     | test_part_nofk_c       | test_part_nofk_c_lvl_idx       |            | CREATE INDEX test_part_nofk_c_lvl_idx ON public.test_part_nofk_c USING btree (lvl)
 public     | test_part_nofk_d       | test_part_nofk_d_lvl_idx       |            | CREATE INDEX test_part_nofk_d_lvl_idx ON public.test_part_nofk_d USING btree (lvl)
 public     | test_part_nofk_default | test_part_nofk_default_lvl_idx |            | CREATE INDEX test_part_nofk_default_lvl_idx ON public.test_part_nofk_default USING btree (lvl)
(6 rows)
postgres=#
H) Now we have both non-partition and partition tables available. Let us try to query the tables using preference clause to see the performance difference.
explain analyze select * from public.test_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';
postgres=# explain analyze select * from public.test_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';
QUERY PLAN |
 Seq Scan on test_nofk  (cost=0.00..3.26 rows=26 width=74) (actual time=0.011..0.041 rows=26 loops=1)
   Filter: (hosptl = 'AAAAAAAAAAAAAAAAAAAA'::text)
   Rows Removed by Filter: 75
 Planning Time: 0.203 ms
 Execution Time: 0.057 ms

postgres=# explain analyze select * from public.test_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';
                                              QUERY PLAN
------------------------------------------------------------------------------------------------------
 Seq Scan on test_nofk  (cost=0.00..3.26 rows=26 width=74) (actual time=0.013..0.043 rows=26 loops=1)
   Filter: (hosptl = 'AAAAAAAAAAAAAAAAAAAA'::text)
   Rows Removed by Filter: 75
 Planning Time: 0.054 ms
 Execution Time: 0.059 ms
(5 rows)
postgres=#


The above result is consistent after couple of runs.

explain analyze select * from public.test_part_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';

postgres=# explain analyze select * from public.test_part_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';
                                                         QUERY PLAN                                                       
----------------------------------------------------------------------------------------------------------------------------
 Seq Scan on test_part_nofk_a test_part_nofk  (cost=0.00..1.32 rows=26 width=74) (actual time=0.012..0.021 rows=26 loops=1)
   Filter: (hosptl = 'AAAAAAAAAAAAAAAAAAAA'::text)
 Planning Time: 0.148 ms
 Execution Time: 0.039 ms
(4 rows)
postgres=# explain analyze select * from public.test_part_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';
                                                         QUERY PLAN                                                       
----------------------------------------------------------------------------------------------------------------------------
 Seq Scan on test_part_nofk_a test_part_nofk  (cost=0.00..1.32 rows=26 width=74) (actual time=0.011..0.020 rows=26 loops=1)
   Filter: (hosptl = 'AAAAAAAAAAAAAAAAAAAA'::text)
 Planning Time: 0.089 ms
 Execution Time: 0.037 ms
(4 rows)
postgres=#

So we get .037ms with partitioned table vs 0.059 for a nonpartitioned table.
We could see the same # of rows processed but there is nothing to filter in partition case.
I) Let us rename the nonpart table and index now...

alter table test_nofk rename to test_nofk_old;
alter index test_nofk_lvl_idx rename to test_nofk_old_lvl_idx;

postgres=# alter table test_nofk rename to test_nofk_old;
ALTER TABLE
postgres=#

postgres=# select * from pg_indexes where tablename='test_nofk_old';
 schemaname |   tablename   |     indexname     | tablespace |                                 indexdef                   
------------+---------------+-------------------+------------+--------------------------------------------------------------------------
 public     | test_nofk_old | test_nofk_lvl_idx |            | CREATE INDEX test_nofk_lvl_idx ON public.test_nofk_old USING btree (lvl)
(1 row)
postgres=#

postgres=# alter index test_nofk_lvl_idx rename to test_nofk_old_lvl_idx;
ALTER INDEX
postgres=#

postgres=# select * from pg_indexes where tablename='test_nofk_old';
 schemaname |   tablename   |       indexname       | tablespace |                                   indexdef             
------------+---------------+-----------------------+------------+------------------------------------------------------------------------------
 public     | test_nofk_old | test_nofk_old_lvl_idx |            | CREATE INDEX test_nofk_old_lvl_idx ON public.test_nofk_old USING btree (lvl)
(1 row)
postgres=#
J) Let us rename the partitioned table to the actual table name..
 alter table test_part_nofk rename to test_nofk;
 alter table test_part_nofk_a rename to test_nofk_a;
 alter table test_part_nofk_b rename to test_nofk_b;
 alter table test_part_nofk_c rename to test_nofk_c;
 alter table test_part_nofk_d rename to test_nofk_d;
 alter table test_part_nofk_default rename to test_nofk_default;

Output:
postgres=#  alter table test_part_nofk rename to test_nofk;
ALTER TABLE
postgres=#  alter table test_part_nofk_a rename to test_nofk_a;
ALTER TABLE
postgres=#  alter table test_part_nofk_b rename to test_nofk_b;
ALTER TABLE
postgres=#  alter table test_part_nofk_c rename to test_nofk_c;
ALTER TABLE
postgres=#  alter table test_part_nofk_d rename to test_nofk_d;
ALTER TABLE
postgres=#  alter table test_part_nofk_default rename to test_nofk_default;
ALTER TABLE
postgres=#

K) Index rename:

alter index test_part_nofk_lvl_idx rename to test_nofk_lvl_idx;
alter index test_part_nofk_a_lvl_idx rename to test_nofk_a_lvl_idx;
alter index test_part_nofk_b_lvl_idx rename to test_nofk_b_lvl_idx;
alter index test_part_nofk_c_lvl_idx rename to test_nofk_c_lvl_idx;
alter index test_part_nofk_d_lvl_idx rename to test_nofk_d_lvl_idx;
alter index test_part_nofk_default_lvl_idx rename to test_nofk_default_lvl_idx;

Output:

postgres=# alter index test_part_nofk_lvl_idx rename to test_nofk_lvl_idx;
ALTER INDEX
postgres=#  alter index test_part_nofk_a_lvl_idx rename to test_nofk_a_lvl_idx;
ALTER INDEX
postgres=#  alter index test_part_nofk_b_lvl_idx rename to test_nofk_b_lvl_idx;
ALTER INDEX
postgres=#  alter index test_part_nofk_c_lvl_idx rename to test_nofk_c_lvl_idx;
ALTER INDEX
postgres=#  alter index test_part_nofk_d_lvl_idx rename to test_nofk_d_lvl_idx;
ALTER INDEX
postgres=#  alter index test_part_nofk_default_lvl_idx rename to test_nofk_default_lvl_idx;
ALTER INDEX
postgres=#

Post the action:

postgres=# \d
                            List of relations
 Schema |              Name               |       Type        |  Owner
--------+---------------------------------+-------------------+----------
..
 public | test_nofk                       | partitioned table | postgres
 public | test_nofk_a                     | table             | postgres
 public | test_nofk_b                     | table             | postgres
 public | test_nofk_c                     | table             | postgres
 public | test_nofk_d                     | table             | postgres
 public | test_nofk_default               | table             | postgres
 public | test_nofk_old                   | table             | postgres

postgres=# \dt+ test_nofk*
                                                 List of relations
 Schema |       Name        |       Type        |  Owner   | Persistence | Access method |    Size    | Description
--------+-------------------+-------------------+----------+-------------+---------------+------------+-------------
 public | test_nofk         | partitioned table | postgres | permanent   |               | 0 bytes    |
 public | test_nofk_a       | table             | postgres | permanent   | heap          | 16 kB      |
 public | test_nofk_b       | table             | postgres | permanent   | heap          | 16 kB      |
 public | test_nofk_c       | table             | postgres | permanent   | heap          | 16 kB      |
 public | test_nofk_d       | table             | postgres | permanent   | heap          | 16 kB      |
 public | test_nofk_default | table             | postgres | permanent   | heap          | 8192 bytes |
 public | test_nofk_old     | table             | postgres | permanent   | heap          | 24 kB      |
(7 rows)

postgres=# \di+ test_nofk*
                                                               List of relations
 Schema |           Name            |       Type        |  Owner   |       Table       | Persistence | Access method |    Size    | Description
--------+---------------------------+-------------------+----------+-------------------+-------------+---------------+------------+-------------
 public | test_nofk_a_lvl_idx       | index             | postgres | test_nofk_a       | permanent   | btree         | 16 kB      |
 public | test_nofk_b_lvl_idx       | index             | postgres | test_nofk_b       | permanent   | btree         | 16 kB      |
 public | test_nofk_c_lvl_idx       | index             | postgres | test_nofk_c       | permanent   | btree         | 16 kB      |
 public | test_nofk_d_lvl_idx       | index             | postgres | test_nofk_d       | permanent   | btree         | 16 kB      |
 public | test_nofk_default_lvl_idx | index             | postgres | test_nofk_default | permanent   | btree         | 8192 bytes |
 public | test_nofk_lvl_idx         | partitioned index | postgres | test_nofk         | permanent   | btree         | 0 bytes    |
 public | test_nofk_old_lvl_idx     | index             | postgres | test_nofk_old     | permanent   | btree         | 16 kB      |
(7 rows)
postgres=#

postgres=# \d+ test_nofk_lvl_idx
         Partitioned index "public.test_nofk_lvl_idx"
 Column |  Type   | Key? | Definition | Storage | Stats target
--------+---------+------+------------+---------+--------------
 lvl    | integer | yes  | lvl        | plain   |
btree, for table "public.test_nofk"
Partitions: test_nofk_a_lvl_idx,
            test_nofk_b_lvl_idx,
            test_nofk_c_lvl_idx,
            test_nofk_default_lvl_idx,
            test_nofk_d_lvl_idx
Access method: btree

postgres=# \d+ test_nofk
                                   Partitioned table "public.test_nofk"
 Column  |  Type   | Collation | Nullable | Default | Storage  | Compression | Stats target | Description
---------+---------+-----------+----------+---------+----------+-------------+--------------+-------------
 lvl     | integer |           |          |         | plain    |             |              |
 dob     | date    |           |          |         | plain    |             |              |
 hosptl  | text    |           |          |         | extended |             |              |
 fn      | text    |           |          |         | extended |             |              |
 ln      | text    |           |          |         | extended |             |              |
 poscode | text    |           |          |         | extended |             |              |
Partition key: LIST (hosptl)
Indexes:
    "test_nofk_lvl_idx" btree (lvl)
Partitions: test_nofk_a FOR VALUES IN ('AAAAAAAAAAAAAAAAAAAA'),
            test_nofk_b FOR VALUES IN ('BBBBBBBBBBBBBBBBBBBA'),
            test_nofk_c FOR VALUES IN ('CCCCCCCCCCCCCCCCCCCA'),
            test_nofk_d FOR VALUES IN ('DDDDDDDDDDDDDDDDDDDA'),
            test_nofk_default DEFAULT
postgres=#

postgres=# select * from pg_indexes where indexname like 'test_nofk%' order by indexname;
 schemaname |     tablename     |         indexname         | tablespace |                                       indexdef 
------------+-------------------+---------------------------+------------+--------------------------------------------------------------------------------------
 public     | test_nofk_a       | test_nofk_a_lvl_idx       |            | CREATE INDEX test_nofk_a_lvl_idx ON public.test_nofk_a USING btree (lvl)
 public     | test_nofk_b       | test_nofk_b_lvl_idx       |            | CREATE INDEX test_nofk_b_lvl_idx ON public.test_nofk_b USING btree (lvl)
 public     | test_nofk_c       | test_nofk_c_lvl_idx       |            | CREATE INDEX test_nofk_c_lvl_idx ON public.test_nofk_c USING btree (lvl)
 public     | test_nofk_d       | test_nofk_d_lvl_idx       |            | CREATE INDEX test_nofk_d_lvl_idx ON public.test_nofk_d USING btree (lvl)
 public     | test_nofk_default | test_nofk_default_lvl_idx |            | CREATE INDEX test_nofk_default_lvl_idx ON public.test_nofk_default USING btree (lvl)
 public     | test_nofk         | test_nofk_lvl_idx         |            | CREATE INDEX test_nofk_lvl_idx ON ONLY public.test_nofk USING btree (lvl)
 public     | test_nofk_old     | test_nofk_old_lvl_idx     |            | CREATE INDEX test_nofk_old_lvl_idx ON public.test_nofk_old USING btree (lvl)
(7 rows)
postgres=#

L) Test the performance of the renamed table...

explain analyze select * from public.test_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';

Output:
postgres=# explain analyze select * from public.test_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';
                                                    QUERY PLAN
------------------------------------------------------------------------------------------------------------------
 Seq Scan on test_nofk_a test_nofk  (cost=0.00..1.32 rows=26 width=74) (actual time=0.008..0.017 rows=26 loops=1)
   Filter: (hosptl = 'AAAAAAAAAAAAAAAAAAAA'::text)
 Planning Time: 0.181 ms
 Execution Time: 0.033 ms
(4 rows)
Time: 0.659 ms
postgres=#
...
postgres=# explain analyze select * from public.test_nofk where hosptl='AAAAAAAAAAAAAAAAAAAA';
                                                    QUERY PLAN
------------------------------------------------------------------------------------------------------------------
 Seq Scan on test_nofk_a test_nofk  (cost=0.00..1.32 rows=26 width=74) (actual time=0.010..0.019 rows=26 loops=1)
   Filter: (hosptl = 'AAAAAAAAAAAAAAAAAAAA'::text)
 Planning Time: 0.089 ms
 Execution Time: 0.035 ms
(4 rows)
Time: 0.374 ms
postgres=#

Around .0033 secs or so. Not much different from prerename state.

Thanks

No comments:

Post a Comment

Flashback data archive steps

 Objective: Ways to track DML changes in a table Detailed objective: We should be able to track the changes in the table at any point in tim...