现在我们可以做到了!
现在我们可以直接从 JSONb 转换为 SQL 数据类型。我正在使用 PostgreSQL v12.3,它运行良好:
SELECT (j->'i')::int, (j->>'i')::int, (j->'f')::float, (j->>'f')::float
FROM (SELECT '{"i":123,"f":12.34}'::jsonb) t(j);
子问题:
-
可能从哪个版本开始?
-
是语法糖还是real conversion?
-
如果真正的“二进制 JSONb → 二进制 SQL” 转换,微优化在哪里?
例如,比“二进制 JSONb → 字符串 → 二进制 SQL” 更快(?) ? boolean→boolean,number→numeric,number→int,number→bigint;数字→浮点数,数字→双精度。
-
为什么不针对 NULL 进行优化?
奇怪的是“NULL 到 SqlType”不起作用,“错误:无法将 jsonb null 转换为整数类型”。
基准建议
如何检查? PostgreSQL 何时优化循环查询?
EXPLAIN ANALYSE SELECT (j->'i')::int, (j->'f')::float -- bynary to bynary INT and FLOAT
-- EXPLAIN ANALYSE SELECT (j->>'i')::int, (j->>'f')::float -- string to bynary INT and FLOAT
-- EXPLAIN ANALYSE SELECT (j->'i')::numeric, (j->'f')::numeric -- bynary to bynary NUMERIC
-- EXPLAIN ANALYSE SELECT (j->>'i')::numeric, (j->>'f')::numeric -- string to bynary NUMERIC
FROM (
SELECT (('{"i":'||x||',"f":'||x||'.34}')::jsonb) as j FROM generate_series(1,599999) g(x)
-- SELECT (('{"i":123,"f":12.34}')::jsonb) as j FROM generate_series(1,599999) g(x)
) t;
PostgreSQL 错误?
即使是现在,2021 版本 pg13 版本...不强制转换 NULL 是没有意义的:自然是将 NULL::int 强制转换为整数,但 PostgreSQL 在自动强制转换中失败:
SELECT (j->'i')::int FROM (SELECT '{"i":null}'::jsonb) t(j); -- fail
导致“错误:无法将 jsonb null 转换为整数类型”。