2016-03-30 21 views
0

私は、顧客の購入日と顧客の最後の電子メールのクリック/オープン日の2つのデータセットを外部ソースから取得しています。これは、それぞれ2つのテーブルPURCHASE_INTERおよびACTIVITY_INTERテーブルに格納されます。購入データは複数で、最後の購入日を取得する必要があります。しかし、活動データは各顧客に固有です。データは互いに独立しており、他のデータセットは存在していない可能性があります。 2つのテーブルを結合し、外部ソースから来た顧客のIDであるperson_idに基づいてグループをグループ化し、最新の日付を取得し、customerテーブルと結合して顧客の電子メールを取得し、別のテーブルと再び結合する、このデータは、それが挿入操作か更新操作かを知るために最終的に格納されます。このクエリのパフォーマンスをどのように向上させるかをお勧めします。それはひどく遅く、10時間以上かかります。 PURCHASE_INTERテーブルとACTIVITY_INTERテーブルには何百万ものレコードが入っています。パフォーマンスを向上させる

  • ACTIVITY_INTER(JOB_ID, PERSON_ID, LAST_CLICK_DATE, LAST_OPEN_DATE)
  • PURCHASE_INTER(JOB_ID, PERSON_ID, LAST_PURCHASE_DATE)
  • CUSTOMER(PERSON_ID)
  • INTERACTION(CUSTOMER_ID)

(最初TWの場合:

SELECT INTER.*, C.ID AS CUSTOMER_ID, C.EMAIL AS CUSTOMER_EMAIL, LSI.ID AS INTERACTION_ID, ROW_NUMBER() OVER (ORDER BY PERSON_ID ASC) AS RN FROM (
    SELECT PERSON_ID    AS PERSON_ID, 
     MAX(LAST_CLICK_DATE) AS LAST_CLICK_DATE, 
     MAX(LAST_OPEN_DATE)  AS LAST_OPEN_DATE, 
     MAX(LAST_PURCHASE_DATE) AS LAST_PURCHASE_DATE 
    FROM (
    SELECT ACT.PERSON_ID AS PERSON_ID, 
      ACT.LAST_CLICK_DATE AS LAST_CLICK_DATE, 
      ACT.LAST_OPEN_DATE AS LAST_OPEN_DATE, 
      NULL AS LAST_PURCHASE_DATE 
    FROM ACTIVITY_INTER ACT 
    WHERE ACT.JOB_ID = 77318317 
    UNION 
    SELECT PUR.PERSON_ID AS PERSON_ID, 
      NULL AS LAST_CLICK_DATE, 
      NULL AS LAST_OPEN_DATE, 
      PUR.LAST_PURCHASE_DATE AS LAST_PURCHASE_DATE 
    FROM PURCHASE_INTER PUR 
    WHERE PUR.JOB_ID = 77318317 
    ) GROUP BY PERSON_ID 
) INTER LEFT JOIN CUSTOMER C ON INTER.PERSON_ID = C.PERSON_ID 
     LEFT JOIN INTERACTION LSI ON C.ID = LSI.CUSTOMER_ID; 
+0

重複を削除する必要がありますか、または「UNION」ではなく「UNION ALL」を使用できますか? – jarlh

+0

特定のジョブに一致するレコードの数はいくつですか? –

+0

'RN'カラムは本当に必要ですか?多数の行を返す場合は、計算するのに費用がかかる可能性があります。 –

答えて

5

あなたのクエリは、次のインデックスを示唆します最初の列が他の2つよりも重要です。

また、UNIONUNION ALLに変更してください。 UNIONは、重複を削除するためのオーバーヘッドが発生します。これは、各サブクエリが異なる列を返すため、少なくとも2つのサブクエリの間では実行できません。

はまた、あなたが最初にサブクエリを交換したい場合がありますfull outer join:凝集がテーブル上で直接実行されるため

SELECT COALESCE(a.PERSON_ID, p.PERSON_ID) as PERSON_ID, 
     a.LAST_CLICK_DATE, a.LAST_OPEN_DATE,p.LAST_PURCHASE_DATE 
FROM (SELECT ACT.PERSON_ID AS PERSON_ID, 
      MAX(ACT.LAST_CLICK_DATE) AS LAST_CLICK_DATE, 
      MAX(ACT.LAST_OPEN_DATE) AS LAST_OPEN_DATE 
     FROM ACTIVITY_INTER ACT 
     WHERE ACT.JOB_ID = 77318317 
     GROUP BY ACT.PERSON_ID 
    ) a FULL OUTER JOIN 
    (SELECT PUR.PERSON_ID AS PERSON_ID, 
      MAX(PUR.LAST_PURCHASE_DATE) AS LAST_PURCHASE_DATE 
     FROM PURCHASE_INTER PUR 
     WHERE PUR.JOB_ID = 77318317 
     GROUP BY PER.PERSON_ID 
    ) p 
    ON a.PERSON_ID = p.PERSON_ID 

これは、オラクル社の最適化のためのより多くのオプションを提供します - 作りインデックスとよりよい統計処理のために利用可能である。

+0

ありがとうございました。本当に役に立ちました。私は多くの新しいことを学びました。 –

関連する問題