大数据转JSON别用to_json

本文探讨了在Ruby on Rails中使用不同方法生成JSON数据的速度差异。通过对比发现,使用`JSON.generate(data)`比内置的`to_json`方法更快,有效提升了API响应速度。

本文转载,http://blog.hellolucky.info/articles/ruby-on-rails-large-amounts-of-data-transfer-json-the-use-json-generate-data/

 

最近在等设计,空闲时间就tune一下api server。因为我一直很纳闷,为何action只是很单纯的到Redis捞出数据吐json,也没有什么特别的动作,到redis捞数据只需要10ms,可是最后renderjson的时候竟然变成70~80ms,一整个很扯。

 

一开始的想法以为是Rails的包袱太重,所以我的方向朝向调整api controller,于是我就把ActionController::Base换成ActionController::Metal,一开始很兴奋的测试,只render text的时候的确快到爆炸,不过当我开始捞数据吐json的时候,速度其实和原本差不多。

 

突然脑袋灵机一动,把data.to_s试看看,速度快了约30ms,当下有点傻眼,后来google了一下to_json真的是个很慢的method,改成JSON.generate(data)的话一样快了约30ms

 

 

之后有空的时候再测试一下https://github.com/msgpack/msgpack-ruby,速度快又省空间

 

 

<think>我们正在讨论的是PostgreSQL中的`row_to_json`函数。根据引用[1]和引用[3],该函数用于将一行记录换为JSON对象。同时,引用[4]提到了与JSON相关的其他函数,但用户问题明确指向`row_to_json`。 函数语法: row_to_json(record [, pretty_bool]) 参数说明: - record: 要换的行记录。 - pretty_bool: 可选参数,如果为true,则在生成的JSON中添加换行和空格(美化输出),默认不添加。 示例1(基本使用): 引用[1]中的例子:`row_to_json(row(1,'foo'))` 返回 `{"f1":1,"f2":"foo"}`。 这里,`row(1,'foo')`创建了一个包含两个字段(f1和f2)的行,然后换为JSON对象。 示例2(从表中选取一行换): 引用[1]中的SQL示例: ```sql SELECT row_to_json(e) FROM (SELECT * FROM "Students" WHERE "Id"=2) e; ``` 这个查询会从"Students"表中选取Id为2的行,并将其换为一个JSON对象。 示例3(使用美化输出): 引用[3]中的例子:`select row_to_json(row(1,'foo'),true);` 输出会包含换行和空格,使JSON更易读(在命令行中可能不明显,但在应用程序中处理字符串时会有格式)。 注意事项: 1. 换后的JSON对象的键名是行中的列名(或别名)。如果行是由子查询或行构造器(如row(1,'foo'))生成,则默认列名为f1, f2, ...(除非指定别名)。 2. 如果希望自定义JSON键名,可以在子查询中为列指定别名。 示例4(使用别名): ```sql SELECT row_to_json(sub) FROM ( SELECT 1 AS id, 'foo' AS name ) sub; ``` 输出:`{"id":1, "name":"foo"}` 示例5(换整个表的多行): 如果想将整个表的多行都换为JSON对象,可以结合使用`json_agg`函数: ```sql SELECT json_agg(row_to_json(t)) FROM ( SELECT id, name FROM "Students" LIMIT 10 ) t; ``` 这样会返回一个包含10个JSON对象的数组。 另外,引用[4]提到的`jsonb_populate_recordset`函数是用于将JSON数组换回记录集的,与`row_to_json`功能相反。 总结: - `row_to_json`用于将单行记录换为JSON对象。 - 可选参数`pretty_bool`用于美化输出(添加换行和空格)。 - 在子查询中为列设置别名可以控制JSON对象的键名。 根据引用[2],PostgreSQL对JSON的支持非常强大,但使用这些函数时需要注意版本兼容性(如示例中使用了PostgreSQL 16)。 现在,我们按照要求生成相关问题:</think>### PostgreSQL `row_to_json` 函数详解 `row_to_json` 是 PostgreSQL 中用于将行记录换为 JSON 对象的函数,特别适用于将关系型数据换为 JSON 格式。以下是详细使用方法和示例: #### 1. 基本语法 ```sql row_to_json(record [, pretty_bool]) ``` - **record**:要换的行记录(可以是表行或子查询结果) - **pretty_bool**(可选):设为 `true` 时美化输出(添加换行和缩进) #### 2. 核心功能 - 将单行数据换为 JSON 对象 - 字段名自动映射为 JSON 键名 - 支持嵌套换(通过子查询处理复杂结构) #### 3. 使用示例 **示例 1:基本换** ```sql -- 将字面量行JSON SELECT row_to_json(row(1, 'foo')); -- 结果 {"f1":1, "f2":"foo"} -- 自动生成字段名 f1, f2[^1][^3] ``` **示例 2:美化输出** ```sql -- 添加换行和缩进 SELECT row_to_json(row(1, 'foo'), true); /* 结果 { "f1": 1, "f2": "foo" } */[^3] ``` **示例 3:换表数据** ```sql -- 创建示例表 CREATE TABLE students ( id SERIAL PRIMARY KEY, name TEXT, score INT ); INSERT INTO students (name, score) VALUES ('Alice', 95); -- 单行换 SELECT row_to_json(s) FROM students s WHERE id = 1; -- 结果 {"id":1, "name":"Alice", "score":95}[^1] ``` **示例 4:带别名的子查询** ```sql -- 自定义 JSON 键名 SELECT row_to_json(student_data) FROM ( SELECT id AS student_id, name AS full_name FROM students ) AS student_data; -- 结果 {"student_id":1, "full_name":"Alice"}[^1] ``` **示例 5:嵌套 JSON 换** ```sql -- 创建关联表 CREATE TABLE courses ( student_id INT REFERENCES students(id), course_name TEXT ); INSERT INTO courses VALUES (1, 'Math'), (1, 'Physics'); -- 嵌套 JSON 换 SELECT s.name, (SELECT json_agg(row_to_json(c)) FROM courses c WHERE c.student_id = s.id) AS courses FROM students s; /* 结果 { "name": "Alice", "courses": [ {"student_id":1, "course_name":"Math"}, {"student_id":1, "course_name":"Physics"} ] } */[^4] ``` #### 4. 注意事项 1. **字段命名**: - 默认使用 `f1, f2,...` 作为键名 - 通过子查询别名可自定义键名(如示例 4) 2. **数据类型映射**: - PostgreSQL 类型自动JSON 类型(如 `integer → number`) - `NULL` 值JSON 的 `null` 3. **性能优化**: - 避免在大数据集直接使用 - 结合 `WHERE` 条件限制处理范围 - 对常用字段创建索引[^2] 4. **版本兼容**: - 需 PostgreSQL 9.2+(完整 JSON 支持) - JSONB 类型在 9.4+ 性能更优[^2] #### 5. 相关函数 - `json_agg()`:聚合多行结果为 JSON 数组 - `jsonb_build_object()`:手动构建 JSON 对象 - `json_populate_record()`:反向换(JSON → 行)[^4] --- ### 常见问题解答 **Q:如何去掉默认的 `f1, f2` 字段名?** A:通过子查询定义列别名: ```sql SELECT row_to_json(t) FROM (SELECT 1 AS id, 'test' AS name) t ``` **Q:能换数组类型吗?** A:需结合 `json_agg`: ```sql SELECT json_agg(row_to_json(s)) FROM students s ``` **Q:换时如何处理 NULL 值?** A:默认JSON `null`,可用 `COALESCE` 替换: ```sql SELECT row_to_json( (SELECT s FROM students s WHERE id=1) ) - 'score' -- 移除 score 字段 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值