Postgres и Пустота

от автора

Только что натолкнулся на возможность Postgresql, показавшуюся мне забавной.
Для кого "боян" — респект вам, я несколько лет работаю с Postgres и до сих пор не натыкался на такую штуку.

select; без указания полей, таблицы и условий возвращает одну строку.
Но у этой строки нет полей:

=> select; -- (1 row)

Для сравнения:

=> select null;  ?column?  ----------  (1 row) => select null where 0=1;  ?column?  ---------- (0 rows)

А сможем ли мы создать таблицу из такого "пустого" запроса? Таблицу без полей.

Да пожалуйста:

=> create table t as select; SELECT 1 => \d+ t                           Table "t"  Column | Type | Modifiers | Storage | Stats target | Description  --------+------+-----------+---------+--------------+------------- => select * from t; -- (1 row)

А можем ли мы в неё вставить?
Легко:

=> insert into t select; INSERT 0 1 => insert into t select; INSERT 0 1 => select * from t; -- (3 rows) => select count(*) from t;  count  -------      3

ЕЩЕ!

=> insert into t select from generate_series(1,1000000); INSERT 0 1000000

Интересно, будет ли Postgresql сканировать такую таблицу?

=> explain analyze select * from t;                                                  QUERY PLAN                                                  ------------------------------------------------------------------------------------------------------------  Seq Scan on t  (cost=0.00..13438.67 rows=1000167 width=0) (actual time=0.018..96.389 rows=1000003 loops=1)  Planning time: 0.024 ms  Execution time: 134.654 ms (3 rows)

Да, честно сканирует. Больше 100 ms — вполне себе заметное время.
Ну и чтобы убедиться, что всё по честному, посмотрим сколько места занимает наша супер-полезная таблица:

=> select pg_size_pretty(pg_total_relation_size('t'));  pg_size_pretty  ----------------  27 MB (1 row)

То есть таблица есть, занимает место на диске, в блоках хранятся разные служебные данные, ну а то, что в ней нет полей — бывает, дело житейское!

=> select t.xmin, t.ctid from t limit 10;   xmin   |  ctid   ---------+--------  1029645 | (0,1)  1029647 | (0,2)  1029648 | (0,3)  1029649 | (0,4)  1029649 | (0,5)  1029649 | (0,6)  1029649 | (0,7)  1029649 | (0,8)  1029649 | (0,9)  1029649 | (0,10) (10 rows)

Я не придумал, зачем может понадобиться такая таблица. Но возможность есть, и это хорошо!

ссылка на оригинал статьи https://habrahabr.ru/post/329856/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *