我的目标是浏览我的数据集,逐日比较每个ITEM_NO
/ LOC
,并确定VAL
从前一天发生变化的日期。现在,我这样做是通过排序,创建一列行号,将表连接到自己的行,然后只选择VAL
已更改的行。
每个月有大约5亿条记录。总共有大约27亿条记录。数据存储在DB2 BLU中。该表已包含ITEM_NO
,LOC
和ARCV_DATE
的索引。我只有select
访问该表。
我认为最大的瓶颈是select语句中的order by
,因为n
是如此之大。我的一个想法是逐月进行分类,然后将每个月合并在一起。
这是我到目前为止所拥有的:
with x as (
select ITEM_NO, LOC, ARCV_DATE, VAL, ROW_NUMBER() over (order by ITEM_NO, LOC, ARCV_DATE) as RN
from MY_SCHEMA.MY_TABLE a
where
ARCV_DATE >= '2017-06-01'
and ARCV_DATE < '2017-07-01'
)
SELECT
x.ITEM_NO,
x.LOC,
y.ARCV_DATE as CHANGE_DATE,
y.VAL,
x.VAL as OLD_VAL
FROM x
INNER JOIN x AS y
ON x.rn = y.rn + 1
WHERE
x.VAL <> y.VAL
and x.ITEM_NO = y.ITEM_NO
and x.LOC = y.LOC
我可以做些什么来提高此类数据集的性能?
答案 0 :(得分:2)
没有任何写入权限,您的选项非常有限,因为查询并不复杂。您可以尝试通过使用LAG()OVER()来完全避免连接:
SELECT
*
FROM (
SELECT
ITEM_NO
, LOC
, ARCV_DATE
, VAL
, LAG(ARCV_DATE, 1) OVER (PARTITION BY ITEM_NO, LOC ORDER BY ARCV_DATE DESC) AS CHANGE_DATE
, LAG(VAL, 1) OVER (PARTITION BY ITEM_NO, LOC ORDER BY ARCV_DATE DESC) AS OLD_VAL
FROM MY_SCHEMA.MY_TABLE
WHERE ARCV_DATE >= '2017-06-01'
AND ARCV_DATE < '2017-07-01'
) d
WHERE ( VAL <> OLD_VAL OR OLD_VAL IS NULL )
但进一步调整可能需要添加或更改索引。
答案 1 :(得分:1)
SELECT currentval.ITEM,
currentval.LOC
currentval.ARCV_DATE currentdate
prevval.ARCV_DATE Previousdate
currentval.val currentval
prevval.val Previousval
FROM MY_SCHEMA.MY_TABLE currentval JOIN
MY_SCHEMA.MY_TABLE prevval ON
currentval.ITEM_NO = prevval.ITEM_NO
WHERE currentval.loc = prevval.loc
AND currentval.val <> prevval.val
AND currentval.ARCV_DATE = prevval.ARCV_DATE+1
AND currentval.ARCV_DATE >= '2017-06-01'
AND prevval.ARCV_DATE < '2017-07-01'
假设价值会从一天变为第二天。此查询将检索从前一天更改为当前日期的值。
AND currentval.ARCV_DATE = prevval.ARCV_DATE+1