In PostgreSQL ( as well as in other rdbms ) you can define columns as arrays. What I wondered is: What is more efficient when it comes to space: Creating several columns or just creating once column as array? The result, at least for me, is rather surprising.
First, let’s create a table with columns of type int:
postgres=# create table single_values ( a int, b int, c int, d int, e int, f int, g int, h int, i int, j int ); CREATE TABLE postgres=# \d single_values Table "public.single_values" Column | Type | Modifiers --------+---------+----------- a | integer | b | integer | c | integer | d | integer | e | integer | f | integer | g | integer | h | integer | i | integer | j | integer |
Next create a table with just one column of type array[int]:
postgres=# create table arr_values ( a int[] ); CREATE TABLE
Ready for populating the first table;
truncate table single_values; \timing on Timing is on. DO $$DECLARE ln int := 1000; BEGIN for i in 0..1e6 loop insert into single_values (a,b,c,d,e,f,g,h,i,j) values (ln,ln,ln,ln,ln,ln,ln,ln,ln,ln); end loop; END$$; DO Time: 4225.313 ms postgres=#
And the table with the array column:
truncate table arr_values; \timing on Timing is on. DO $$DECLARE larr int[] := '{1000,1000,1000,1000,1000,1000,1000,1000,1000,1000}'; BEGIN for i in 0..1e6 loop insert into arr_values (a) values (larr); end loop; END$$;
postgres=# \i populate_arr_values.sql TRUNCATE TABLE DO Time: 4033.523 ms postgres=#
Now, what about the size?
postgres=# select pg_size_pretty(pg_relation_size('single_values')); pg_size_pretty ---------------- 65 MB (1 row) Time: 0.227 ms postgres=# select pg_size_pretty(pg_relation_size('arr_values')); pg_size_pretty ---------------- 89 MB (1 row) Time: 0.737 ms
I did expect the table with the array to be smaller but it is the other way around. The table with the 10 columns is smaller. In the next post I’ll do the same for oracle.