使用postgres

时间:2017-08-02 12:51:42

标签: sql postgresql performance query-performance postgresql-performance

我有两张桌子

条目


 id    | val1 | val2
-------+------+------+
 ent_1 | xxx  | xxx
 ent_2 | xyy  | yyy
 ent_3 | zxz  | zzz
 ent_4 | zxz  | zzz

entries_list


 id  | entry_id | val1 | val2
-----+----------+------+-------
   1 |   ent_1  | xxx  | xxx
   2 |   ent_1  | xyy  | yyy
   3 |   ent_2  | zxz  | zzz
   4 |   ent_2  | zxz  | zzz

entries_list.entry_id 是来自 entries.id

的forigen键

所以我需要找到具有相应entries引用的entry_list。我不希望在entries中没有任何引用的entry_list,而我期待的结果是

[{
    id: ent_1,
    entries: [{
        id: 1,
        val1: xxx,
        val2: xxx
    }, {
        id: 1,
        val1: xxx,
        val2: xxx
    }]
}, {
    id: ent_2,
    entries: [{
        id: 3,
        val1: xxx,
        val2: xxx
    }, {
        id: 4,
        val1: xxx,
        val2: xxx
    }]
}]

由于期望的结果和结构,我决定使用 Json_agg Json_build_object 查询看起来像这样

SELECT entries.id, 
       Json_agg(Json_build_object('id', list.id, 'val1', list.val2, 'val2', 
       list.val2)) AS sub_list 
FROM   entries 
       INNER JOIN (SELECT id,val1,val2 
                   FROM   entries_list) AS list 
               ON entries.id = list.entry_id
GROUP  BY entries.id 
ORDER  BY entries.id 

但对于1M记录,它的表现非常糟糕,差不多10秒。那么更改这个的更好方法是什么?

我想以计划方式获取数据并将其分组到sql之外的代码中,但是如何在两种方法中修改查询。?

我有nodejs后端和pg模块作为连接器。

2 个答案:

答案 0 :(得分:1)

此版本的表现如何?

SELECT e.id, 
       (SELECT Json_agg(Json_build_object('id', el.id, 'val1', el.val2, 'val2', 
       el.val2))
        FROM entries_list el 
        WHERE el.entry_id = e.id
       ) as sub_list 
FROM entries e 
ORDER BY e.id ;

对于性能,您需要entries_list(entry_id, id, val2)上的索引。第一把钥匙特别重要。

答案 1 :(得分:1)

您可以使用exists代替常规加入:

select 
    entry_id, 
    json_agg(json_build_object('id', id, 'val1', val2, 'val2', val2)) as sub_list 
from entries_list
where exists (
    select 1 
    from entries e 
    where entry_id = e.id)
group by entry_id 
order by entry_id;

entries_list(entry_id)上需要entries(id)上的索引(显然,它可能是主键)。