gra*_*bot 5 postgresql json query-optimization
我目前在PostgreSQL中使用这个JSON转义函数作为未来原生JSON支持的代表.虽然它有效,但它也限制了我们的系统性能.我该如何进行优化呢?也许某种查找数组?
CREATE OR REPLACE FUNCTION escape_json(i_text TEXT)
RETURNS TEXT AS
$body$
DECLARE
idx INTEGER;
text_len INTEGER;
cur_char_unicode INTEGER;
rtn_value TEXT := i_text;
BEGIN
-- $Rev: $ --
text_len = LENGTH(rtn_value);
idx = 1;
WHILE (idx <= text_len) LOOP
cur_char_unicode = ASCII(SUBSTR(rtn_value, idx, 1));
IF cur_char_unicode > 255 THEN
rtn_value = OVERLAY(rtn_value PLACING (E'\\u' || LPAD(UPPER(TO_HEX(cur_char_unicode)),4,'0')) FROM idx FOR 1);
idx = idx + 5;
text_len = text_len + 5;
ELSE
/* is the current character one of the following: " \ / bs ff nl cr tab */
IF cur_char_unicode IN (34, 92, 47, 8, 12, 10, 13, 9) THEN
rtn_value = OVERLAY(rtn_value PLACING (E'\\' || (CASE cur_char_unicode
WHEN 34 THEN '"'
WHEN 92 THEN E'\\'
WHEN 47 THEN '/'
WHEN 8 THEN 'b'
WHEN 12 THEN 'f'
WHEN 10 THEN 'n'
WHEN 13 THEN 'r'
WHEN 9 THEN 't'
END)
)
FROM idx FOR 1);
idx = idx + 1;
text_len = text_len + 1;
END IF;
END IF;
idx = idx + 1;
END LOOP;
RETURN rtn_value;
END;
$body$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
忏悔:我是Google Summer of Code 2010学生,他试图将JSON支持带到PostgreSQL 9.1.虽然我的代码功能相当完整,但它还没有为上游做好准备,而PostgreSQL开发社区正在研究一些替代实现.然而,随着春假即将到来,我希望能够完成我的重写,并在本周给予最后的推动.
同时,您可以下载并安装正在进行中的JSON数据类型模块,该模块应该适用于PostgreSQL 8.4.0及更高版本.它是一个PGXS模块,因此您可以编译和安装它,而无需编译所有PostgreSQL.但是,您将需要PostgreSQL服务器开发标头.
安装如下:
git clone git://git.postgresql.org/git/json-datatype.git
cd json-datatype/
USE_PGXS=1 make
sudo USE_PGXS=1 make install
psql -f json.sql <DBNAME1> # requires database superuser privileges
Run Code Online (Sandbox Code Playgroud)
虽然构建和安装只需要完成一次,但是json.sql需要在计划使用JSON数据类型的每个数据库上运行.
安装完成后,您现在可以运行:
=> SELECT to_json(E'"quotes and \n newlines"\n'::TEXT);
to_json
--------------------------------
"\"quotes and \n newlines\"\n"
(1 row)
Run Code Online (Sandbox Code Playgroud)
请注意,这不会转义非ASCII字符.
我所有的方法归结为"以其他方式做":
根据我的经验,pl/pgsql在这种情况下并不快 - 它的优势在于它与数据库交换数据的整体支持,而不是作为通用编程语言.
例:
create or replace function escape_json_perl(text) returns text
strict immutable
language plperlu as $$
use JSON;
return JSON->new->allow_nonref->encode($_[0]);
$$;
Run Code Online (Sandbox Code Playgroud)
快速测试表明这比plpgsql函数快15倍(虽然它返回你可能想要剥离的值的引号)
| 归档时间: |
|
| 查看次数: |
5162 次 |
| 最近记录: |