Бенчмарк: bigint vs int на PostgreSQL
Я хочу повысить производительность своей базы данных. В проекте все таблицы перешли от int
к bigint
, что я считаю плохим выбором не только в отношении хранения, поскольку int
требует 4 bytes
, а bigint
требует 8 bytes
; но и в отношении производительности.
Поэтому я создал небольшую таблицу с10 миллионами записей, со скриптом в Python:
import uuid
rows=10000000
output='insert_description_bigint.sql'
f = open(output, 'w')
set_schema="SET search_path = norma;n"
f.write(set_schema)
for i in range(1,rows):
random_string=uuid.uuid4()
query="insert into description_bigint (description_id, description) values (%d, '%s'); n"
f.write(query % (i,random_string))
И вот как я создал свои two
таблицы:
-- BIGINT
DROP TABLE IF EXISTS description_bigint;
CREATE TABLE description_bigint
(
description_id BIGINT PRIMARY KEY NOT NULL,
description VARCHAR(200),
constraint description_id_positive CHECK (description_id >= 0)
);
select count(1) from description_bigint;
select * from description_bigint;
select * from description_bigint where description_id = 9999999;
-- INT
DROP TABLE IF EXISTS description_int;
CREATE TABLE description_int
(
description_id INT PRIMARY KEY NOT NULL,
description VARCHAR(200),
constraint description_id_positive CHECK (description_id >= 0)
);
После вставки всех этих данных я делаю запрос для обеих таблиц, чтобы измерить разница между ними. И к моему удивлению, они оба имеют одинаковое представление:
select * from description_bigint; -- 11m55s
select * from description_int; -- 11m55s
Я делаю что-то не так с моим эталоном ? Разве int
не должно быть быстрее, чем bigint
? Особенно, когда primary key
по определению является index
, что означает, что создание индекса для bigint
будет медленнее, чем создание индекса для int
, с тем же количеством данных, верно ?
Я знаю, что это не просто мелочь, которая окажет огромное влияние на мою производительность. база данных, но я хочу убедиться, что мы используем лучшие практики и сосредоточены на производительности здесь.
1 ответ:
В 64-системе эти две таблицы почти идентичны. Столбец
description_id
вdescription_int
занимает 8 байт (4 для целого числа и 4 для выравнивания). Попробуйте этот тест:select pg_relation_size('description_int')/10000000 as table_int, pg_relation_size('description_bigint')/10000000 as table_bigint, pg_relation_size('description_int_pkey')/10000000 as index_int, pg_relation_size('description_bigint_pkey')/10000000 as index_bigint;
Средний размер строк обеих таблиц практически одинаков. Это происходит потому, что целочисленный столбец занимает 8 байт (4 байта для значения и 4 байта выравнивания) точно так же, как bigint (8 байт для значения без наполнителя). То же самое относится и к индексным записям. Однако это особый случай. Если мы добавим еще один целочисленный столбец к первая таблица:
CREATE TABLE two_integers ( description_id INT PRIMARY KEY NOT NULL, one_more_int INT, description VARCHAR(200), constraint description_id_positive CHECK (description_id >= 0) );
Средний размер строки должен оставаться прежним.
Подробнее см. В разделе вычисление и экономия места в PostgreSQL.