我必须解决我班上有关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。感谢。
答案 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)