2016-03-30 215 views
0

我有兩組數據來自外部來源 - 客戶的購買日期和最後一次電子郵件點擊/客戶的開放日期。這分別存儲在兩個表PURCHASE_INTER和ACTIVITY_INTER表中。購買數據爲多個,我需要提取上次購買日期。但活動數據對每個客戶都是唯一的。數據彼此獨立,其他數據集可能不存在。我們編寫了下面的查詢,它將兩個表結合在一起,根據來自外部來源的客戶的id(person_id)進行分組,並獲取最新的日期,加入我們的客戶表以獲取客戶電子郵件,並再次與另一個表爲了知道它是插入還是更新操作,最終將存儲這些數據。您能否建議我如何改進此查詢的性能。這是非常緩慢,超過10個小時。有數百萬條記錄進入PURCHASE_INTER和ACTIVITY_INTER表。提高性能

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 ALL'而不是'UNION'? – jarlh

+0

有多少條記錄符合給定的工作? –

+0

你真的需要提供'RN'列嗎?如果您要返回大量的行,那麼計算起來可能會很昂貴。 –

回答

5

您所查詢的建議如下指標:

  • 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 o索引,第一列比其他兩個更重要,除非匹配的數量非常大)。

另外,將UNION更改爲UNION ALLUNION招致開銷刪除重複 - 這是不可能的(至少在兩個子查詢之間),因爲每個子查詢返回不同的列。

此外,你可能要替換第一子查詢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

非常感謝您的幫助。這真的很有幫助。我學到了很多新東西。 –