PostgreSQL - 对SUM和LEFT JOIN的查询优化

时间:2014-04-10 10:02:26

标签: sql database postgresql

我使用to_char()来表示这个月,这在Table1Table2两个表格中很常见。

但在表2中,我有日期和月份。

我也在Table1上创建了一个索引。如果我只用Table1编写相同的查询,我会在1000毫秒内得到结果。

我使用左联接来获取值的总和并合并结果。

这是查询。

SELECT
    "month", -- Table2
    sum("value1"), -- Table2
    sum("value2") -- Table1
FROM Table2
LEFT JOIN Table1 ON
    Table2."month" = to_char(Table1.Date, 'Mon-yy')
WHERE Table2.Date BEtween '2014-01-01' AND '2014-03-01'
GROUP BY "month"

查询说明:

"GroupAggregate  (cost=88133.61..3688425.12 rows=2 width=15)"
"  ->  Merge Left Join  (cost=88133.61..2707006.48 rows=130855816 width=15)"
"        Merge Cond: (Table2.month = (to_char((Table1.date)::timestamp with time zone, 'Mon-yy'::text)))"
"        ->  Sort  (cost=8922.32..9056.34 rows=53609 width=11)"
"              Sort Key: Table2.month"
"              ->  Seq Scan on Table2(cost=0.00..3885.28 rows=53609 width=11)"
"                    Filter: ((date >= '2014-01-01'::date) AND (date   Materialize  (cost=79211.29..81652.22 rows=488186 width=8)"
"              ->  Sort  (cost=79211.29..80431.75 rows=488186 width=8)"
"                    Sort Key: (to_char((Table1.date)::timestamp with time zone, 'Mon-yy'::text))"
"                    ->  Seq Scan on Table1(cost=0.00..19735.86 rows=488186 width=8)"

目前我在Table1中有大约500k行。

我每天都会用表3中的大约3到4k记录更新表格。

查询一直在运行。

我没有结果。

我可以告诉我哪里出错了吗?

1 个答案:

答案 0 :(得分:1)

要使您的查询“高效”运行,您将需要2个索引。 从解释来看,table2需要一个日期列的索引。

CREATE INDEX ON table2 using btree(date);

table1将需要一个带有月份名称和日期编号的计算索引,例如“APR-14”。

CREATE INDEX ON table1 using btree(to_char(date, 'Mon-yy'));

[编辑,因为a_horse_with_no_name说这不起作用,因为to_char不是不可变的 - 你可以通过编写自己的不可变函数来解决这个问题,但实际上如果你只存储一个日期列就会更简单!]

也就是说,文本匹配比日期或数字慢,如果您想订购信息,您只能按字母顺序排序。