I am working on a scenario to store strings in hex
format of fixed length 64 to database. Obviously the choices are BYTEA
and CHAR(64)
.
Initial thought was to enforce a valid hex string storing it as BYTEA
will be good idea, but impact I evaluated was the use of ENCODE
on select queries.
I did some performance benchmarks, considering both tables have few million rows;
# A file query_with_char.sql
SELECT "key" FROM table_varchar;;
# A file query_with_binary.sql
SELECT ENCODE("key", 'hex') FROM table_binary;
pgbench -c 30 -T 120 -n -f ./query_with_binary.sql -f ./query_with_char.sql -P 5 -S my_db
SQL script 1: ./query_with_binary.sql
- weight: 1 (targets 33.3% of total)
- 236 transactions (34.6% of total, tps = 1.876072)
- latency average = 8896.888 ms
- latency stddev = 2548.701 ms
SQL script 2: ./query_with_varchar.sql
- weight: 1 (targets 33.3% of total)
- 225 transactions (33.0% of total, tps = 1.788628)
- latency average = 7164.604 ms
- latency stddev = 2209.866 ms
I am unable to understand why the performance of query ENCODE
is faster compared to normal string. How is PostgreSQL able to do encoding on million rows faster than just fetching the string columns?
Can someone explain what might be wrong in the above test?
Best Answer
encode()
is a very cheap function. I would not expect any measurable impact at all in your test.The difference is almost certainly due to the much smaller storage size of
bytea
as compared tochar(64)
. Consider:The dominant factor for performance of simple
SELECT
queries is the number of data pages that have be read."Best" data type?
If your goal is to optimize performance, consider a third option:
2
uuid
columnsTo understand, first read:
And:
Then consider this demo (executed on pg 11, but true for all modern versions):
RAM size:
Disk size (compressed format):
db<>fiddle here
The seemingly minor difference between 33 and 32 bits can actually make a difference of 8 bytes, because several storage mechanisms require padding at multiples of 8 bytes.
Repeat your test with 2 UUIDs. I am confident it will come out on top.