postgresql的查询优化

时间:2014-12-10 19:37:04

标签: sql postgresql optimization

我必须解决我班上有关postgresql中查询优化的问题。

我必须优化以下查询。

“如果订单数量超过系统中所有订单的平均数量,并且会将其发送给客户,则查询会确定每年的收入损失。”

select  sum(ol_amount) / 2.0 as avg_yearly
from    orderline, (select   i_id, avg(ol_quantity) as a
            from     item, orderline
            where    i_data like '%b'
                 and ol_i_id = i_id
            group by i_id) t
where   ol_i_id = t.i_id
    and ol_quantity < t.a

是否可以通过索引或其他方式优化该查询(物化视图也可以)?

可以找到执行计划here。感谢。

2 个答案:

答案 0 :(得分:1)

首先,如果你必须从数据背面进行搜索,只需在数据的反面创建一个索引

create index on item(reverse(i_data);

然后像这样查询:

select  sum(ol_amount) / 2.0 as avg_yearly
from    orderline, (select   i_id, avg(ol_quantity) as a
            from     item, orderline
            where    reverse(i_data) like 'b%'
                 and ol_i_id = i_id
            group by i_id) t
where   ol_i_id = t.i_id
    and ol_quantity < t.a

答案 1 :(得分:0)

请记住,当您必须检索表格的30%时,制作索引可能无法加快查询速度。在这种情况下,位图索引可能对您有所帮助,但据我记得它在Postgres中不可用。所以,想想要索引哪个表,也许值得用 ol_i_id 来索引大表,因为你所做的连接只需要匹配不到10%的大表并加载小表ram(我可能会在这里弄错,但至少在SAS散列连接中意味着你将较小的表加载到ram)。

您可以尝试在进行任何连接之前聚合数据并重复使用分组数据。我假设您需要在一个查询中执行所有操作,而无需手动显式创建任何临时表。最近,我一直在SQL Server上工作很多,所以我可能会混合语法,但试一试。我对表格的数据和结构做了很多假设,但希望它能起作用。

;WITH GrOrderline (
  SELECT ol_i_id, ol_quantity, SUM(ol_amount) AS Yearly, Count(*) AS cnt
  FROM orderline 
  GROUP BY ol_i_id, ol_quantity
),
WITH AvgOrderline (
  SELECT 
    o.ol_i_id, SUM(o.ol_quantity)/SUM(cnt) AS AvgQ
  FROM GrOrderline AS o 
  INNER JOIN item AS i ON (o.ol_i_id = i.i_id AND RIGHT(i.i_data, 1) = 'b')
  GROUP BY o.ol_i_id
)
  SELECT SUM(Yearly)/2.0 AS avg_yearly
  FROM GrOrderline o INNER JOIN AvgOrderline a ON (a.ol_i_id = a.ol_i_id AND o.ol_quantity < a.AvG)