另一种方法是提取hex
表示中的最后 6 个字符,在前面加上一个x
并直接转换:
db=# SELECT ('x' || right('\x00000000000001'::bytea::text, 6))::bit(24)::int;
int4
------
1
.. 这比get_byte()
路由短一点,但也是 PostgreSQL 的一个未记录的特性。但是,我在这里引用Tom Lane 的话:
这依赖于位类型输入转换器的一些未记录的行为,但我认为没有理由期望它会中断。一个可能更大的问题是它需要 PG >= 8.3,因为在此之前没有要强制转换的文本。
此相关答案中的详细信息:
这假定您的设置bytea_output
is hex
,这是自 9.0 版以来的默认设置。可以肯定的是,您可以为您的会话测试/设置它:
SET bytea_output = 'hex';
更多在这里:
表现
我在一个有 10k 行的表上运行了一个测试(最好的 10 个)。get_byte()
在 Postgres 9.1 中实际上要快一些:
CREATE TEMP TABLE t (a bytea);
INSERT INTO t
SELECT (12345670000000 + generate_series(1,10000))::text::bytea;
位移与乘法/加法一样快:
SELECT
('x' || right(a::text, 6))::bit(24)::int -- 34.9 ms
,(get_byte(a, 11) << 16) + (get_byte(a, 12) << 8) + get_byte(a, 13) -- 27.0 ms
,(get_byte(a, 11) << 16) | (get_byte(a, 12) << 8) | get_byte(a, 13) -- 27.1 ms
, get_byte(a, 11) * 65536 + get_byte(a, 12) * 256 + get_byte(a, 13) -- 27.1 ms
FROM t