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:
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;
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=# create index test_nofk_lvl_idx on test_nofk(lvl);
CREATE INDEX
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=#
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=#
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=#
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);
postgres=# create index test_part_nofk_lvl_idx ON public.test_part_nofk USING btree (lvl);
CREATE INDEX
postgres=#
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=#
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;
ALTER TABLE
postgres=#
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=#
ALTER INDEX
postgres=#
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;
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;
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=#
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
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)
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=#
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
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=#
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=#
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_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.
No comments:
Post a Comment