2013-06-24 35 views
0

我們有一個簡單的查詢即將運行。我可以說超過10個小時。事實表有170多億行。有關改進以下查詢性能的任何建議或最佳做法?針對長時間運行的查詢的建議

SELECT 
    /*+ parallel(f 4) */ 
    F.DM_CUSTOMER_DKEY, 
    P.PRODUCT_YEAR, 
    SUM(F.ADVG_COST_ACTUALS) advg_cost_actuals 
FROM DM_CUST_RENEWAL_ADV_FACT F 
INNER JOIN DM_PRODUCT_HIERARCHY p 
ON F.DM_PRODUCT_HKEY = P.DM_PRODUCT_HKEY 
GROUP BY F.DM_CUSTOMER_DKEY, 
    P.PRODUCT_YEAR 
ORDER BY P.PRODUCT_YEAR 

這裏是計劃

OPERATION OBJECT_NAME OPTIONS COST PARTITION_START PARTITION_STOP 
SELECT STATEMENT 10931402 
PX COORDINATOR 
PX SEND :TQ10005 QC (ORDER) 10931402 
SORT ORDER BY 10931402 
PX RECEIVE 10931402 
PX SEND :TQ10004 RANGE 10931402 
SORT GROUP BY 10931402 
PX RECEIVE 10931402 
PX SEND :TQ10003 HASH 10931402 
SORT GROUP BY 10931402 
HASH JOIN 1964410 
Access Predicates 
F.DM_PRODUCT_HKEY=P.DM_PRODUCT_HKEY 
PX RECEIVE 335 
PX SEND :TQ10002 BROADCAST 335 
VIEW index$_join$_002 335 
HASH JOIN BUFFERED 
Access Predicates 
ROWID=ROWID 
PX RECEIVE 136 
PX SEND :TQ10000 HASH 136 
PX 
BLOCK 
ITERATOR 136 
INDEX DM_PRODUCT_HIERARCHY_PK FAST FULL 
SCAN 
136 
PX RECEIVE 280 
PX SEND :TQ10001 HASH 280 
PX 
BLOCK 
ITERATOR 280 
INDEX DM_PRODUCT_HIERARCHY_LPK FAST FULL 
SCAN 
280 
PX BLOCK ITERATOR 1878718 1 369 
TABLE ACCESS DM_CUST_RENEWAL_ADV_FACT FULL 1878718 1 369 
+0

不幸的是,這不是那麼容易:發佈查詢是不夠的信息來幫助你。 –

+0

執行計劃?有沒有DM_CUST_RENEWAL_ADV_FACT的索引。 DM_PRODUCT_HKEY? –

+0

那麼,你可以開始思考添加一個篩選器到您的查詢。或者你真的需要爲整個事實表彙總這些值? (如果是這樣的話,你應該爲此考慮一個OLAP解決方案) – Lamak

回答

0

正如前面已經說過,儘量正確索引你的表。 我想分割該表http://docs.oracle.com/cd/B10501_01/server.920/a96524/c12parti.htm

分割它由F.DM_CUSTOMER_DKEY或P.PRODUCT_YEAR或它們兩個。 或者至少你可以把where語句縮短到product_year左右,然後運行多個查詢

+1

我沒有看到索引或分區如何幫助這裏。你能擴展你的答案來解釋嗎? –

+0

它會幫助,如果他嘗試與where語句...然後他可以爲該選擇編寫函數 –

+0

以及它*可能*幫助,但這似乎是一個不同的問題的答案。 –

0

我假設表DM_PRODUCT_HIERARCHY足夠小,以便在查詢執行時適合內存。在這種情況下,散列連接是最好的,你不需要索引。您可以嘗試使用NO_INDEX提示,也可以使用USE_HASH提示。

您可以通過非常大的事實表的DM_CUSTOMER_DKEY對結果進行分組。 通過此屬性對事實表進行分區將極大地提高性能。

您還應該考慮創建一個彙總的事實表。這可以是ETL過程的一部分。也許物化視圖會起作用。但是,我對大型物化視圖的體驗非常糟糕。特別是如果源表中有很多更改,則會遇到底層技術的限制。

要獲得關於「最佳」運行時的感覺,您應該測量事實表上全表掃描的時間。確保您計算沒有索引的列(樣例中的COLUMN_X),否則您將測量掃描索引而不是表的時間。

SELECT count(COLUMN_X) from DM_CUST_RENEWAL_ADV_FACT;