[英]DB2 SQL: fastest way to get lagged value of many columns
有很多方法可以獲取SQL中某個列的滯后值,例如:
WITH CTE AS (
SELECT
rownum = ROW_NUMBER() OVER (ORDER BY columns_to_order_by),
value
FROM table
)
SELECT
curr.value - prev.value
FROM CTE cur
INNER JOIN CTE prev on prev.rownum = cur.rownum - 1
,要么:
select variable_of_interest
,lag(variable_of_interest ,1)
over(partition by
some_group order by variable_1,...,variable_n)
as lag_variable_of_interest
from DATA
我使用第二個版本,但是當“滯后”許多變量時,我的代碼運行非常慢,因此我的代碼變成:
select variable_of_interest_1
,variable_of_interest_2
,variable_of_interest_3
,lag(variable_of_interest_1 ,1)
over(partition by
some_group order by variable_1,...,variable_n)
as lag_variable_of_interest_1
,lag(variable_of_interest_2 ,1)
over(partition by
some_group order by variable_1,...,variable_n)
as lag_variable_of_interest_2
,lag(variable_of_interest_3 ,1)
over(partition by
some_group order by variable_1,...,variable_n)
as lag_variable_of_interest_3
from DATA
我想知道,這是因為每個滯后函數都必須按其自己的分區對整個數據集進行排序,即使它們使用相同的分區和順序也是如此嗎?
我不確定100%DB2如何優化此類查詢。 如果它獨立執行每個滯后,那么肯定有改進優化程序的空間。
你可以使用一種方法是lag()
與join
主鍵 :
select t.*, tprev.*
from (select t.*, lag(id) over ( . . . ) as prev_id
from t
) t left join
t tprev
on t.id = tprev.prev_id ;
根據您的描述,這可能是最有效的方法。
這應該比row_number()
更有效,因為row_number()
可以利用索引。
如果所有OLAP函數都使用相同的PARTITION BY
和ORDER BY
,則Db2將僅對數據排序一次。 您可以通過查看解釋計划來確認。
create table data(v1 int, v2 int, v3 int, g1 int, g2 int, o1 int, o2 int) organize by row
;
explain plan for
select g1
, g2
, o1
, o2
, v1
, v2
, v3
, lag(v1) over(partition by g1, g2 order by o1, o2 ) as lag_v1
, lag(v2) over(partition by g1, g2 order by o1, o2 ) as lag_v2
, lag(v3) over(partition by g1, g2 order by o1, o2 ) as lag_v3
from
data
;
將給出以下計划(使用db2exfmt -1 -d $DATABASE
)。 您可以看到只有一個SORT
運算符
Access Plan:
-----------
Total Cost: 14.839
Query Degree: 4
Rows
RETURN
( 1)
Cost
I/O
|
1000
LMTQ
( 2)
14.839
2
|
1000
TBSCAN
( 3)
14.5555
2
|
1000
SORT
( 4)
14.5554
2
|
1000
TBSCAN
( 5)
14.2588
2
|
1000
TABLE: PAUL
DATA
Q1
順便說一句,如果您使用真實的SQL查詢發布問題(以及一些DDL和一些數據量的概念),我們也許可以提出一些建議,以提高獲取滯后值的性能。 不看更好的例子就很難提供詳細的建議
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.