簡體   English   中英

DB2 SQL:獲得許多列的滯后值的最快方法

[英]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 BYORDER 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM