Pull to refresh

Comments 13

Тут все просто, дело в выравнивании. Если у вас 64-разрядная архитектура, то поля в записи, имеющие длину 8 байт и более, будут выровнены по 8 байт.

То есть, если поле имеет длину 8 байт или больше восьми байт, то оно будет выровнено по 8 байт.


Так процессор умеет быстрее читать их из памяти. Поэтому 4-байтные int нужно складывать рядом, тогда они будут занимать вместе 8 байт.

4 байта меньше чем 8 байт, а в предыдущем предложении сказано, что выровнены будут поля, которе больше. Либо там ошибка, либо я не совсем понял его смысл.


Я вообще думал, что по 8 байт выравниваются любые поля. Не важно, больше они или меньше.

Гм, кажется я понял свою ошибку. Там в таблице 3 поля — два по 4 байта и одно 8 байт. В задаче порядок такой — сначала поле в 4 байта, потом поле в 8 байт, потом опять поле в 4 байта.


Так как поля размером 8 байт или больше должны быть выровнены по 8 байт — между первым четырёхбайтным полем и вторым полем размером в 8 байт будет дырка в 4 байта. И можно поставить последнее четырёхбайтное поле в эту дырку, тем самым сэкономив 4 байта.

Да, всё верно.
Можете посмотреть с помощью pageinspect, или в докладе Шаплова, упоминавшемся в Статье.
Правильно ли я понял, что amclusterable в pg_am есть только Postgres от Postgres Professional? В ванильном постгресе я вижу только amname, amhandler и amtype.
К сожалению, в 9.6 это убрали (как следствие, и в Postgres Pro тоже). В 9.5.* еще можно смотреть. В более новых версиях придется лезть в исходники. Или есть функция pg_index_has_property, с помощью которой можно посмотреть для конкретного индекса, возможна ли кластеризация. Примерно вот так:
select pg_index_has_property('index_name_or_oid', 'clusterable');
Добавил это в статью, спасибо за замечание.

В номинации "Лучшие вопросы" я бы выделил 3 и 4. Уж больно интересные и полезные
За статью спасибо!


Победители викторины получили промокоды, которые они могут ввести вместо оплаты участия в PgConf.Russia 2018

Есть ещё какие-то способы попасть на конференцию?

Конечно, есть! Во-первых, уже открыт прием докладов, во-вторых, можно зарегистрироваться и для участия без доклада. Заходите http://pgconf.ru/ — сейчас пока действуют самые низкие цены.

И еще мы проводим небольшую конференцию pgconf.Сибирь в Новосибирске 23-24 сентября.
UFO just landed and posted this here
Многие вообще на дух не переносят GUI. Большинство остальных любит PgAdmin3 или думает, что его любит (привыкло). меньше народу любит PgAdmin4 и Jet Brains'овский DataGrip.
Взрывоопасность темы предпочтений в GUI и отсутствие согласия — одна из причин отсутствия GUI в коробке постгреса. Однако в Postgres Pro Enterprise нам предстоит выпустить и GUI-шное средство управления.
Вот в этой статье рассмотрено несколько вариантов:
https://habrahabr.ru/company/pgdayrussia/blog/325642/

Я лично из комментариев к этой статьи открыл для себя DBeaver и теперь нарадоваться не могу.
На postgres 9.6, как минимум, команда просмотра заголовка для таблицы выдаёт ошибку:
SELECT * FROM heap_page_items(get_raw_page('t1', 0)) limit 1;

ERROR: block number 0 is out of range for relation «t1»

Вероятно стоит добавить что для этого требуется в таблицу вставить хотя бы один кортеж.
Не могли бы вы пожалуйста пояснить подробнее про хранение NULL и что нужно было увидеть с помощью Pageinspect?

Я пытаюсь разобрать приведённый вами пример:

CREATE TABLE t1(x int, y int);
CREATE TABLE t2(x int not null, y int not null);
INSERT INTO t1 VALUES (1, 1)
SELECT * FROM heap_page_items(get_raw_page('t1', 0)) limit 1;

Вывод:

 lp     lp_off     lp_flags     lp_len     t_xmin     t_xmax     t_field3     t_ctid     t_infomask2     t_infomask     t_hoff     t_bits     t_oid     t_data           
 -----  ---------  -----------  ---------  ---------  ---------  -----------  ---------  --------------  -------------  ---------  ---------  --------  ---------------- 
 1      8160       1            32         4302       0          0            (0,1)      2               2048           24         (null)     (null)    0100000001000000


INSERT INTO t2 VALUES (1, 1)
SELECT * FROM heap_page_items(get_raw_page('t2', 0)) limit 1;


Вывод:
 lp     lp_off     lp_flags     lp_len     t_xmin     t_xmax     t_field3     t_ctid     t_infomask2     t_infomask     t_hoff     t_bits     t_oid     t_data           
 -----  ---------  -----------  ---------  ---------  ---------  -----------  ---------  --------------  -------------  ---------  ---------  --------  ---------------- 
 1      8160       1            32         4303       0          0            (0,1)      2               2048           24         (null)     (null)    0100000001000000 


Абсолютно одинаковые.

Пробую вставит null значения:
INSERT INTO t1 VALUES (null, null)
SELECT * FROM heap_page_items(get_raw_page('t1', 0)) limit 1;


 lp     lp_off     lp_flags     lp_len     t_xmin     t_xmax     t_field3     t_ctid     t_infomask2     t_infomask     t_hoff     t_bits     t_oid     t_data           
 -----  ---------  -----------  ---------  ---------  ---------  -----------  ---------  --------------  -------------  ---------  ---------  --------  ---------------- 
 1      8160       1            32         4302       0          0            (0,1)      2               2048           24         (null)     (null)    0100000001000000


И всё равно всё то же самое.

На каком основании сделать какая из них занимает меньше места?

P.S. Форматированный вывод, который выроятно будет удобнее смотреть: paste.fedoraproject.org/paste/z50hMUVlKZ4Idh0mgqTEBQ
Sign up to leave a comment.