Tob*_*ede 26 javascript postgresql v8 plv8
我一直在试验PostgreSQL和PL/V8,它将V8 JavaScript引擎嵌入到PostgreSQL中.使用这个,我可以查询数据库中的JSON数据,这非常棒.
基本方法如下:
CREATE or REPLACE FUNCTION
json_string(data json, key text) RETURNS TEXT AS $$
var data = JSON.parse(data);
return data[key];
$$ LANGUAGE plv8 IMMUTABLE STRICT;
SELECT id, data FROM things WHERE json_string(data,'name') LIKE 'Z%';
Run Code Online (Sandbox Code Playgroud)
使用,V8我可以将JSON数据解析为JS,然后返回一个字段,我可以将其用作常规的pg查询表达式.
但
在大型数据集上,性能可能是一个问题,因为我需要解析数据的每一行.解析器速度很快,但它肯定是过程中最慢的部分,每次都必须发生.
我试图制定出(到最后得到一个实际的问题)是,如果有一种方法可以缓存或预处理的JSON ......即使存储JSON表中的二进制表示,可以由V8使用自动作为JS对象可能是一个胜利.我已经看过使用替代格式,例如messagepack或protobuf,但我不认为它们在任何情况下都必须与原生JSON解析器一样快.
思想
PG有blob和二进制类型,因此数据可以以二进制形式存储,然后我们只需要一种方法将其编组到V8中.
lim*_*der 12
Postgres支持任意函数调用的索引.以下索引应该可以解决问题:
CREATE INDEX json_idx ON things (json_string(field,'name'));
Run Code Online (Sandbox Code Playgroud)
简短的版本似乎是Pg的新json支持,到目前为止,除了序列化的json文本之外,没有办法直接以任何形式存储json.(这似乎在9.4中有所改变)
您似乎想要存储一个预先解析的表单,该表单是v8如何表示内存中json的序列化表示,并且目前不支持.甚至不清楚v8是否提供json结构的任何类型的二进制序列化/反序列化.如果它本身不这样做,则需要将代码添加到Pg以生成这样的表示并将其转换回v8 json数据结构.
它也不一定会更快:
如果json以特定于v8的二进制形式存储,那么将常规json表示返回给客户端的查询必须在每次返回时对其进行格式化,从而产生CPU成本.
二进制序列化版本的json与将v8 json数据结构直接存储在内存中的方式不同.你不能直接编写涉及任何类型的指针图形的数据结构,它必须被序列化.这种序列化和反序列化具有成本,甚至可能不比解析json文本表示快得多.这很大程度上取决于v8如何表示内存中的JavaScript对象.
二进制序列化表示可能很容易变大,因为大多数json是文本和小数字,在这里你不能从二进制表示中获得任何紧凑性.由于存储大小直接影响表扫描的速度,TOAST的值提取,TOASTed值所需的解压缩时间,索引大小等,因此您可以轻松地查询较慢的查询和较大的表.
我有兴趣看看你所描述的优化是否可行,以及它是否真的是一种优化.
为了在进行表扫描时获得所需的好处,我猜你真正需要的是一种可以遍历的格式,而不必解析它并将其转换为可能是javascript对象的malloc()图形.您希望能够为字段提供路径表达式,并直接从序列化表单中将其读取到已将其读入Pg读取缓冲区或shared_buffers中.这将是一个非常有趣的设计项目,但如果在v8中存在类似的东西,我会感到惊讶.
你真正需要做的是研究现有的基于json的对象数据库如何快速搜索任意json路径以及它们的磁盘表示,然后报告pgsql-hackers.也许从已经解决过这个问题的人那里可以学到一些东西 - 当然,假设他们有.
与此同时,我想要关注的是这里的其他答案正在做什么:解决慢点并找到其他方法来做你需要的事情.您还可以考虑帮助优化json解析器,但是取决于v8中的一个还是其他一个正在使用中可能已经远远超过收益递减点.
我想这是速度和灵活数据表示之间需要权衡的领域之一.
也许不是让检索阶段负责解析数据,而是创建一个可以在输入上预先传播 json 数据的新数据类型可能是更好的方法?
http://www.postgresql.org/docs/9.2/static/sql-createtype.html