现在我们可以做到了!
现在我们可以直接从 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);
子问题:
可以从哪个版本开始?
它是语法糖还是真正的转换?
如果是真正的“二进制 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
导致"ERROR: cannot cast jsonb null to type integer"。