クエリの優れたフォーマットでスタート、それはあなたが簡単にコードを理解し、繰り返しパターンに気づくことができます:
SELECT decode (PLANT ,'ECL','CELMA','EDS','CELMA',PLANT)PLANT,
COUNT(*) RECORD_COUNT,
COUNT(DISTINCT OFF.REMD_PART_NUM) REMD_PART_NUM_COUNT,
COUNT(DISTINCT OFF.REMD_PART_SERIAL) REMD_PART_SER_NUM_COUNT,
COUNT(DECODE(LLP_TRACKD_PART_IND,'LL',LLP_TRACKD_PART_IND,NULL)) LL_COUNT,
COUNT(DECODE(LLP_TRACKD_PART_IND,'LR',LLP_TRACKD_PART_IND,NULL)) LR_COUNT,
COUNT(DECODE(LLP_TRACKD_PART_IND,'TR',LLP_TRACKD_PART_IND,NULL)) TR_COUNT,
SUM(OFF.REMD_PART_QTY) TOTAL_REMD_PART_QTY,
SUM(decode(LLP_TRACKD_PART_IND,null,0,
CASE
WHEN REGEXP_LIKE(REMD_PART_TSN, '^-?\d+(\.\d+)?$')
THEN CAST(REMD_PART_TSN AS NUMBER)
ELSE 0
END
)) TOTAL_TSN,
SUM(decode(LLP_TRACKD_PART_IND,null,0,
CASE
WHEN REGEXP_LIKE(REMD_PART_CSN, '^-?\d+(\.\d+)?$')
THEN CAST(REMD_PART_CSN AS NUMBER)
ELSE 0
END
)) TOTAL_CSN
FROM (
with t as (
SELECT distinct PLANT, WORK_ORDER_NUM,ESN,REMD_PART_NUM,REMD_PART_SERIAL,REMD_PART_IIN,
LLP_TRACKD_PART_IND,
REMD_PART_QTY,REMD_PART_TSN,REMD_PART_CSN,REMD_PART_TSO,REMD_PART_CSO
,REMD_PART_TSC,REMD_PART_CSC,REMD_CYCLE_REMAIN
FROM <TABLE1>
WHERE REMD_PART_NUM is not null
)
select DISTINCT PLANT,WORK_ORDER_NUM,ESN,REMD_PART_NUM,REMD_PART_SERIAL
,REMD_PART_IIN
,( select max(LLP_TRACKD_PART_IND)
from t bb
where aa.PLANT=bb.PLANT
and aa.WORK_ORDER_NUM=bb.WORK_ORDER_NUM
and aa.ESN=bb.ESN
and aa.REMD_PART_NUM=bb.REMD_PART_NUM
and aa.REMD_PART_SERIAL=bb.REMD_PART_SERIAL
) LLP_TRACKD_PART_IND
,REMD_PART_QTY
,( select max(REMD_PART_TSN) from t bb
where aa.PLANT=bb.PLANT
and aa.WORK_ORDER_NUM=bb.WORK_ORDER_NUM
and aa.ESN=bb.ESN
and aa.REMD_PART_NUM=bb.REMD_PART_NUM
and aa.REMD_PART_SERIAL=bb.REMD_PART_SERIAL
) REMD_PART_TSN
,
( select max(REMD_PART_CSN) from t bb
where aa.PLANT=bb.PLANT
and aa.WORK_ORDER_NUM=bb.WORK_ORDER_NUM
and aa.ESN=bb.ESN
and aa.REMD_PART_NUM=bb.REMD_PART_NUM
and aa.REMD_PART_SERIAL=bb.REMD_PART_SERIAL
) REMD_PART_CSN
from t aa
) OFF
WHERE REMD_PART_NUM is not null
GROUP BY decode (PLANT ,'ECL','CELMA','EDS','CELMA',PLANT)
;
あなたは、以下のパターンが3繰り返されていることがわかります時間(3つのほぼ同じサブクエリ):
select max(some_field)
from t bb
where aa.PLANT=bb.PLANT
and aa.WORK_ORDER_NUM=bb.WORK_ORDER_NUM
and aa.ESN=bb.ESN
and aa.REMD_PART_NUM=bb.REMD_PART_NUM
and aa.REMD_PART_SERIAL=bb.REMD_PART_SERIAL
この問合せには3つの非常に高価なソート操作があることもわかります。最下位の副問合せに1つのDISTINCT、次に別の副問合せに別のDISTINCT、次に最上位の問合せにGROUP BY操作(DISTINCTの一種)があります。簡単に1つのソート(DISTINCT)このように分析関数を使用して除去することができる唯一のクエリのいずれかに探し
:
SELECT * FROM (
SELECT PLANT,WORK_ORDER_NUM,ESN,REMD_PART_NUM,REMD_PART_SERIAL,
REMD_PART_IIN, REMD_PART_QTY,
max(LLP_TRACKD_PART_IND) over
(partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL)
as LLP_TRACKD_PART_IND,
max(REMD_PART_TSN) over
(partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL)
as REMD_PART_TSN,
max(REMD_PART_CSN) over
(partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL)
as REMD_PART_CSN,
row_number() over
(partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL, REMD_PART_IIN, REMD_PART_QTY
order by PLANT) as Rn
FROM TABLE1
WHERE REMD_PART_NUM is not null
)
WHERE rn = 1
は、最終的なクエリが可能migh:
SELECT decode (PLANT ,'ECL','CELMA','EDS','CELMA',PLANT)PLANT,
COUNT(*) RECORD_COUNT,
COUNT(DISTINCT OFF.REMD_PART_NUM) REMD_PART_NUM_COUNT,
COUNT(DISTINCT OFF.REMD_PART_SERIAL) REMD_PART_SER_NUM_COUNT,
COUNT(DECODE(LLP_TRACKD_PART_IND,'LL',LLP_TRACKD_PART_IND,NULL)) LL_COUNT,
COUNT(DECODE(LLP_TRACKD_PART_IND,'LR',LLP_TRACKD_PART_IND,NULL)) LR_COUNT,
COUNT(DECODE(LLP_TRACKD_PART_IND,'TR',LLP_TRACKD_PART_IND,NULL)) TR_COUNT,
SUM(OFF.REMD_PART_QTY) TOTAL_REMD_PART_QTY,
SUM(decode(LLP_TRACKD_PART_IND,null,0,
CASE
WHEN REGEXP_LIKE(REMD_PART_TSN, '^-?\d+(\.\d+)?$')
THEN CAST(REMD_PART_TSN AS NUMBER)
ELSE 0
END
)) TOTAL_TSN,
SUM(decode(LLP_TRACKD_PART_IND,null,0,
CASE
WHEN REGEXP_LIKE(REMD_PART_CSN, '^-?\d+(\.\d+)?$')
THEN CAST(REMD_PART_CSN AS NUMBER)
ELSE 0
END
)) TOTAL_CSN
FROM (
SELECT PLANT,WORK_ORDER_NUM,ESN,REMD_PART_NUM,REMD_PART_SERIAL,REMD_PART_IIN, REMD_PART_QTY,
max(LLP_TRACKD_PART_IND) over (partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL) as LLP_TRACKD_PART_IND,
max(REMD_PART_TSN) over (partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL) as REMD_PART_TSN,
max(REMD_PART_CSN) over (partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL) as REMD_PART_CSN,
row_number() over (partition by PLANT, WORK_ORDER_NUM, ESN, REMD_PART_NUM, REMD_PART_SERIAL, REMD_PART_IIN, REMD_PART_QTY
order by PLANT) as Rn
FROM TABLE1
WHERE REMD_PART_NUM is not null
)
WHERE rn = 1
GROUP BY decode (PLANT ,'ECL','CELMA','EDS','CELMA',PLANT)
私はこのクエリをさらに最適化できると思っていますが、テーブルの構造と知識が必要ですビジネス要件のge。
ただし、まだ可能なマイクロオプティマイゼーションはあります。
このパターン:
SUM(decode(LLP_TRACKD_PART_IND,null,0,
CASE
WHEN REGEXP_LIKE(REMD_PART_TSN, '^-?\d+(\.\d+)?$')
THEN CAST(REMD_PART_TSN AS NUMBER)
ELSE 0
END
)) TOTAL_TSN,
はこの1に置き換えることができます:
coalesce(
SUM(
CASE
WHEN REGEXP_LIKE(REMD_PART_TSN, '^-?\d+(\.\d+)?$')
THEN CAST(REMD_PART_TSN AS NUMBER)
ELSE 0
END
), 0
)
SUMはNULL値を無視するので、その後、各レコードにNULL値をチェックすることは無駄です。少数のレコード(< 1百万)の場合、それは問題ではありませんが、数億のレコードに対して、スケールの効果を達成することができます。たとえば、各レコードに10.000.000レコードを掛けたものをチェックすると、
微調整? MySQLまたはOracleを使用していますか? (含まれていない製品にタグを付けないでください) – jarlh
@jarlh Oracleです。 –
これはオラクルです。 @jarlh –