Postgres:如何加入

时间:2015-05-18 11:33:52

标签: postgresql

我正在研究Postgres 9.3。我有两张桌子,第一张是付款项目:

                   Table "public.prescription"
      Column       |          Type           |                             Modifiers
-------------------+-------------------------+--------------------------------------------------------------------
 id                | integer                 | not null default nextval('frontend_prescription_id_seq'::regclass)
 presentation_code | character varying(15)   | not null
 presentation_name | character varying(1000) | not null
 actual_cost       | double precision        | not null
 pct_id            | character varying(3)    | not null

第二个是组织:

           Table "public.pct"
      Column       |          Type           | Modifiers
-------------------+-------------------------+-----------
 code              | character varying(3)    | not null
 name              | character varying(200)  |

我有一个查询来获取特定代码的所有付款:

SELECT sum(actual_cost) as total_cost, pct_id as row_id 
FROM prescription 
WHERE presentation_code='1234' GROUP BY pct_id

以下是该查询的query plan

现在,我想用相关组织的name属性注释每一行。这就是我正在尝试的:

SELECT sum(prescription.actual_cost) as total_cost, prescription.pct_id, pct.name as row_id
FROM prescription, pct
WHERE prescription.presentation_code='0212000AAAAAAAA'
GROUP BY prescription.pct_id, pct.name;

这里是ANALYSE for that query。它的速度非常慢:我做错了什么?

我认为必须有一种方法可以在第一个查询运行后使用pct.name注释每一行,这样会更快。

2 个答案:

答案 0 :(得分:2)

使用JOIN(在这种情况下为LEFT JOIN,因为即使没有pct我们也想要行):

SELECT 
    sum(prescription.actual_cost) as total_cost,
    prescription.pct_id,
    pct.name as row_id
FROM prescription
    LEFT JOIN pct ON pct.code = prescription.pct_id
WHERE 
    prescription.presentation_code='0212000AAAAAAAA'
GROUP BY 
    prescription.pct_id,
    pct.name;

我不知道它是否运作良好,我没有尝试过此查询。

答案 1 :(得分:0)

您正在从2个表中获取数据,但不以任何方式加入表。实际上,您可以进行完全连接,从而生成两个表的笛卡尔积。如果查看ANALYZE统计信息,您会发现嵌套循环处理了6200万行。这需要时间。

添加连接条件以快速完成此操作:

SELECT sum(prescription.actual_cost) as total_cost, prescription.pct_id, pct.name as row_id
FROM prescription
JOIN pct On pct.code = prescription.pct_id
WHERE prescription.presentation_code = '0212000AAAAAAAA'
GROUP BY prescription.pct_id, pct.name;