2011-02-14 26 views
4

我目前在PostgreSQL中使用這個JSON轉義函數作爲未來原生JSON支持的一個支持。雖然它有效,但它也限制了我們的系統性能。我怎樣才能優化它?也許某種查詢數組?在PostgreSQL 9.0中優化轉義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; 

回答

5

我所有的方法歸結爲「做一些其他的方式」:

  • 寫在其他一些語言,例如使用PL/Perl裏,PL /蟒蛇,PL /紅寶石
  • 編寫一個包裝圓C語言編寫的
  • 一些外部的JSON庫做的JSON逃脫在客戶端,而不是在查詢中(假設你的客戶有一些很好的JSON逃脫支持)

在我的經驗,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]); 
    $$; 

簡單的測試表明,這是15倍比PLPGSQL函數更快(雖然它返回圍繞價值的報價,你可能想去掉)

+0

我很害怕那個。我只是編碼我沉重的存儲過程在python中,直到他們發佈9.1 – gradbot 2011-02-15 17:59:06

6

的順序懺悔:我是Google Summer of Code 2010的學生,他將嘗試爲PostgreSQL 9.1帶來JSON支持。雖然我的代碼功能完備,但並沒有完全準備好上游,而PostgreSQL開發社區正在尋找一些替代實現。然而,隨着春假的到來,我希望完成我的重寫,並在本週給予最後的推動。

與此同時,您可以下載並安裝work-in-progress JSON data type module,它應該在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 

儘管構建和安裝只需要進行一次,json.sql需要您計劃使用的JSON數據類型上的每個數據庫上運行。

安裝好之後,你就可以執行:

=> SELECT to_json(E'"quotes and \n newlines"\n'::TEXT); 
      to_json    
-------------------------------- 
"\"quotes and \n newlines\"\n" 
(1 row) 

請注意,這並不逃避非ASCII字符。