基准测试:PostgreSQL 上的 bigint 与 int
Benchmark: bigint vs int on PostgreSQL
我想提高我的数据库性能。在一个项目中,所有 table 都从 int
变为 bigint
,我认为这不仅在存储方面是一个糟糕的选择,因为 int
需要 4 bytes
, bigint
需要 8 bytes
;但也与性能有关。
所以我创建了一个小的 table,其中包含 1000 万 个条目,在 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
tables:
的方式
-- 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)
);
插入所有这些数据后,我对两个 table 都进行了查询,以衡量它们之间的差异。令我惊讶的是,它们都具有相同的性能:
select * from description_bigint; -- 11m55s
select * from description_int; -- 11m55s
我的基准测试有问题吗? int
不应该比 bigint
快吗?特别是,当 primary key
定义为 index
时,这意味着为 bigint
创建索引比为 创建索引要慢 =13=],同样的数据量,对吧?
我知道这不仅仅是一件会对我的数据库性能产生巨大影响的小事,但我想确保我们使用最佳实践并专注于这里的性能。
在 64 位系统中,两个 table 几乎相同。 description_int
中的 description_id
列包含 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;
两个 table 的平均行大小几乎相同。这是因为整数列占用 8 个字节(4 个字节用于值和 4 个字节的对齐)与 bigint 完全一样(8 个字节用于没有填充的值)。这同样适用于索引条目。然而,这是一个特例。如果我们在第一个 table:
中再添加一个整数列
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)
);
平均行大小应保持不变,因为前 8 个字节将用于两个整数(无填充符)。
在 Calculating and saving space in PostgreSQL 中查找更多详细信息。
我想提高我的数据库性能。在一个项目中,所有 table 都从 int
变为 bigint
,我认为这不仅在存储方面是一个糟糕的选择,因为 int
需要 4 bytes
, bigint
需要 8 bytes
;但也与性能有关。
所以我创建了一个小的 table,其中包含 1000 万 个条目,在 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
tables:
-- 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)
);
插入所有这些数据后,我对两个 table 都进行了查询,以衡量它们之间的差异。令我惊讶的是,它们都具有相同的性能:
select * from description_bigint; -- 11m55s
select * from description_int; -- 11m55s
我的基准测试有问题吗? int
不应该比 bigint
快吗?特别是,当 primary key
定义为 index
时,这意味着为 bigint
创建索引比为 创建索引要慢 =13=],同样的数据量,对吧?
我知道这不仅仅是一件会对我的数据库性能产生巨大影响的小事,但我想确保我们使用最佳实践并专注于这里的性能。
在 64 位系统中,两个 table 几乎相同。 description_int
中的 description_id
列包含 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;
两个 table 的平均行大小几乎相同。这是因为整数列占用 8 个字节(4 个字节用于值和 4 个字节的对齐)与 bigint 完全一样(8 个字节用于没有填充的值)。这同样适用于索引条目。然而,这是一个特例。如果我们在第一个 table:
中再添加一个整数列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)
);
平均行大小应保持不变,因为前 8 个字节将用于两个整数(无填充符)。
在 Calculating and saving space in PostgreSQL 中查找更多详细信息。