我得到以下查询,我参加了4次。但是返回结果要花费很多时间。 有什么方法可以优化此查询?
SELECT T1.wbd_date as WBD_DATE, to_char(T1.wbd_block_no, 'fm00') as BLOCK_NO, T2.wbd_value as AmbHum, T3.wbd_value as AmbTemp,
T4.wbd_value as SWT, T5.wbd_value as Expval
FROM (
SELECT wbd_attribute_id, wbd_date, wbd_block_no, wbd_value
FROM wb_block_data ) T1
JOIN wb_block_data T2 on T1.wbd_date = T2.wbd_date AND T1.wbd_block_no = T2.wbd_block_no and T2.wbd_attribute_id = 152112 and to_char(T2.wbd_date,'MM YYYY')='07 2019'
JOIN wb_block_data T3 on T1.wbd_date = T3.wbd_date AND T1.wbd_block_no = T3.wbd_block_no and T3.wbd_attribute_id = 152116 and to_char(T3.wbd_date,'MM YYYY')='07 2019'
JOIN wb_block_data T4 on T1.wbd_date = T4.wbd_date AND T1.wbd_block_no = T4.wbd_block_no and T4.wbd_attribute_id = 152120 and to_char(T4.wbd_date,'MM YYYY')='07 2019'
JOIN wb_block_data T5 on T1.wbd_date = T5.wbd_date AND T1.wbd_block_no = T5.wbd_block_no and T5.wbd_attribute_id = 150661 and to_char(T5.wbd_date,'MM YYYY')='07 2019'
答案 0 :(得分:1)
您实质上是在做枢轴操作,使用条件聚合可能会更快:
select wbd_attribute_id, block_no, wbd_date,
max(wbd_value) filter (where wbd_attribute_id = 152112) as AmbHum,
max(wbd_value) filter (where wbd_attribute_id = 152116) as AmbTemp,
max(wbd_value) filter (where wbd_attribute_id = 152120) as swt,
max(wbd_value) filter (where wbd_attribute_id = 152120) as Expval
from (
SELECT wbd_attribute_id, wbd_date, to_char(wbd_block_no, 'fm00') as block_no, wbd_value
FROM wb_block_data
where wbd_attribute_id in (152112, 152116, 152120, 150661)
and wbd_date >= DATE '2019-07-01'
and wbd_date < DATE '2019-08-01'
) t
group by wbd_attribute_id, wbd_date, block_no
您想要为此在(wbd_attribute_id, wbd_date)
上建立索引。
答案 1 :(得分:0)
如下所示的索引可能会起作用:
CREATE INDEX idx ON wb_block_data (wbd_date, wbd_block_no, wbd_attribute_id);
但是,我们还需要使连接条件具有可控性:
SELECT T1.wbd_date as WBD_DATE, to_char(T1.wbd_block_no, 'fm00') as BLOCK_NO, T2.wbd_value as AmbHum, T3.wbd_value as AmbTemp, T4.wbd_value as SWT, T5.wbd_value as Expval
FROM
(
SELECT wbd_attribute_id, wbd_date, wbd_block_no, wbd_value
FROM wb_block_data
) T1
JOIN wb_block_data T2 on T1.wbd_date = T2.wbd_date AND T1.wbd_block_no = T2.wbd_block_no and T2.wbd_attribute_id = 152112 and T2.wbd_date >= '2019-07-01' and T2.wbd_date < '2019-08-01'
JOIN wb_block_data T3 on T1.wbd_date = T3.wbd_date AND T1.wbd_block_no = T3.wbd_block_no and T3.wbd_attribute_id = 152116 and T3.wbd_date >= '2019-07-01' and T3.wbd_date < '2019-08-01'
JOIN wb_block_data T4 on T1.wbd_date = T4.wbd_date AND T1.wbd_block_no = T4.wbd_block_no and T4.wbd_attribute_id = 152120 and T4.wbd_date >= '2019-07-01' and T4.wbd_date < '2019-08-01'
JOIN wb_block_data T5 on T1.wbd_date = T5.wbd_date AND T1.wbd_block_no = T5.wbd_block_no and T5.wbd_attribute_id = 150661 and T5.wbd_date >= '2019-07-01' and T5.wbd_date < '2019-08-01';
我对查询所做的唯一更改是将日期要求表达为一个范围,而没有使用to_char
:
wbd_date >= '2019-07-01' and wbd_date < '2019-08-01'
这是可修改的,这意味着Postgres也许可以使用wbd_date
列上的索引来满足2019年7月的日期范围。
答案 2 :(得分:0)
我将查询更改为此,并因此迅速获得所需的结果
SELECT T1.wbd_date as WBD_DATE, to_char(T1.wbd_block_no, 'fm00') as BLOCK_NO, T2.wbd_value as AmbHum, T3.wbd_value as AmbTemp,
T4.wbd_value as SWT, T5.wbd_value as Expval
FROM (
SELECT wbd_attribute_id, wbd_date, wbd_block_no, wbd_value
FROM wb_block_data where to_char(wbd_date,'MM YYYY')='07 2019') T1
JOIN wb_block_data T2 on T1.wbd_date = T2.wbd_date AND T1.wbd_block_no = T2.wbd_block_no and T2.wbd_attribute_id = 152112
JOIN wb_block_data T3 on T1.wbd_date = T3.wbd_date AND T1.wbd_block_no = T3.wbd_block_no and T3.wbd_attribute_id = 152116
JOIN wb_block_data T4 on T1.wbd_date = T4.wbd_date AND T1.wbd_block_no = T4.wbd_block_no and T4.wbd_attribute_id = 152120
JOIN wb_block_data T5 on T1.wbd_date = T5.wbd_date AND T1.wbd_block_no = T5.wbd_block_no and T5.wbd_attribute_id = 150661