2017-07-19 85 views
-1

考慮:子查詢減緩我的查詢下

  • 的視角DataView的事件。事件存儲在時間戳Inst和數據列中。

  • 事件發生在每天06:00,14:00和20:00的特定輪班或間隔。

  • 該視圖DataView每個班次持有數百個事件,並有幾年積壓。

  • 當前班次的開始時間戳存儲在表CurrShift中。該列與該信息標記爲StartTime該表只包含具有該信息的一行。

目標:

檢索所有事件從目前的轉變,即其中DataView.Inst >= CurrShift.StartTime

解決方案,但是進展緩慢:

SELECT * 
FROM DataTable 
WHERE Inst >= (SELECT StartTime FROM CurrShift); 

查詢運行時間超過30分鐘。對於給定的應用程序這是不可接受的。 ,但僅限於固定日期

更快的查詢

SELECT * 
FROM Data_Table 
WHERE Inst >= TO_DATE('19.07.2017 14:00:00'); 

該查詢運行在下2.0秒。對於給定的應用程序足夠快。

問:

  1. 爲什麼是緩慢相比,第二個第一個解決方案?我猜這個子查詢是針對DataView的每一行執行的,但是希望優化器能夠解決這個問題。

  2. 是否有更高性能/更好的方法來做第一個查詢?使用CurrShift.StartTime比計算應用程序中的時間戳更方便。

@Robbie豐田:是,InstStartTime絕對date類型既是表所示。

@dnoeth: 1.)子查詢只返回一行。該表僅包含當前班次的開始和結束時間戳及其指定。 2.)無論如何,我嘗試了MAX(..),但沒有成功。

解釋計劃 我執行解釋計劃,如羅比建議,並看到計劃的巨大差異。但我不知道做什麼用的信息做:

慢查詢:

SELECTED STATEMENT 
    HASH JOIN RIGHT OUTER 
    TABLE ACCESS FULL 
    HASH JOIN RIGHT OUTER 
     TABLE ACCESS FULL 
     HASH JOIN RIGHT OUTER 
     TABLE ACCESS FULL 
    ... 

快速查詢:

SELECTED STATEMENT 
    NESTED LOOPS OUTER 
    NESTED LOOPS OUTER 
     NESTED LOOPS OUTER 
... 

完全不同的引用的表,和巨大的CPU海岸用於哈希。

+1

InstFROM是一個時間戳嗎?我不在Oracle工作(我是從sql標記來的),但是如果InstFROM與Inst不同,那麼Inst上的索引可能不會被使用。 – RToyo

+0

標量子查詢應返回一行(否則它將失敗),您可能需要頂部應用MAX:WHERE Inst> =(SELECT MAX(Inst)FROM Time_Table)。但我懷疑這是你的行爲想要/需要的。 – dnoeth

+1

那麼,你知道'Time_Table'中只有一行,優化器沒有(除非它是'DUAL')。試試MAX。 – dnoeth

回答

0

嘗試避免與下面的子查詢:

DECLARE t Time_Table.Inst%TYPE; 
SELECT Inst INTO t FROM Time_Table; 
SELECT * FROM Data_Table WHERE Inst >= t; 
+0

這不是Oracle語法。這個問題被標記爲'[oracle]',所以答案需要提出Oracle語法。請注意,'[sql]'只是泛型SQL查詢;有關MS SQL Server的問題被標記爲'[sql-server]' – APC

+0

已更新。我的錯。 – 2017-07-20 17:47:51

0

這解決了問題,2),但它是一個有點凌亂的辦法。 來自原始Fast Solution的TO_DATE()可以用SYSDATE替代,而不會有任何明顯的性能損失。

回顧:

  • 的WHERE與SYSDATE子句運行速度相當快

  • 這是很難計算的轉變的開始時間戳出SYSDATE

  • 有提供開始時間戳的表格

  • A WHERE使用子查詢到該表子句是緩慢

解決方案:

  • 用WHERE子句SYSDATE減少原始數據到當天

  • 過濾子集WHERE子句和子查詢放入開始時間戳表中的速度很快,因爲它只是原始數據的一小部分

代碼:

SELECT * 
FROM (
    SELECT * 
    FROM Data_Table 
    WHERE Inst >= SYSDATE - 1; 
) 
WHERE Inst >= (SELECT StartTime FROM CurrShift); 

執行時間大致是從問題的快速解法 1.5。

關於問題1:

我仍然不知道爲什麼子查詢的速度如此之慢。但我學會了更好地解釋解釋計劃。這個觀點如此複雜和深刻地嵌套,以至於從那裏的解釋計劃開始很困難。有趣的事實:解釋計劃預計查詢運行9小時。