2012-02-20 138 views
1

我在同一個視圖上有兩個選擇。一個選擇將被主鍵過濾,另一個選擇將被過濾在非唯一索引上。使用的視圖很複雜。用主鍵選擇大約需要15秒。具有非唯一索引的選擇需要0.5秒。Oracle SQL:一個選擇需要很長時間,另一個選擇很快

爲什麼使用主鍵的查詢很慢?

我使用「EXPLAIN PLAN FOR」爲兩者創建執行計劃。

的執行計劃快速選擇:fast select

的執行計劃緩慢的選擇:slow select

--Pseudocode 
create table TableA 
(
    ID number, --(Primary Key) 
    ProjectID number, --(Not unique index) 
    TableB_id number, --(Foreign Key to Table TableB) 
    TableC_id number, --(Foreign Key to Table TableC) 
    TableD_id number --(Foreign Key to Table TableD) 
); 



Create view viewX 
as 
Select 
     ID as TableB_ID, 
     0 as TableC_ID, 
     0 as TableD_ID, 
     Value1, 
     Value2 
    from TableB 
union all 
Select 
     0 as TableB_ID, 
     ID as TableC_ID, 
     0 as TableD_ID, 
     Value1, 
     value2 
    from TableC 
union all 
Select 
     0 as TableB_ID, 
     0 as TableC_ID, 
     id as TableD_ID, 
     value1, 
     value2 
    from viewz; 



Create view viewA 
as 
Select 
     t.id, 
     t.ProjectID, 
     x.TableB_ID, 
     x.TableC_ID, 
     x.TableD_ID 
    from TableA t 
    inner join viewX x 
    on t.TableB_ID = x.TableB_ID and 
     t.TableC_ID = x.TableC_ID and 
     t.TableD_ID = x.TableD_ID; 

--this select needs o,5 seconds 
Select * 
    from ViewA 
    where ProjectID = 2220; 


--this select needs 15 seconds 
Select * 
    from viewA 
    where id = 5440; 

的選擇TableA上和ViewX separatly快。

--this select needs 0,5 seconds 
select * 
    from TableA 
    where id = 5440; 

Result: ID = 5440, ProjektID = 2220, TableB_ID = 123, TableC_ID = 5325, TableD_ID = 7654 

--this select needs 0,3 seconds 
Select * 
    viewX x 
    where TableB_ID = 123 and 
     TableC_ID = 5325 and 
     TableD_ID = 7654; 

感謝您的支持

+1

可能是針對第二個查詢的緩存結果(請參閱http://docs.oracle.com/cd/E11882_01/server.112/e16638/memory.htm) – tbone 2012-02-20 11:40:32

+0

要擴展@ tbone的答案,您可以使用兩種方法做有助於消除緩衝的影響。一個是運行每個查詢兩次,只使用第二次運行的結果進行比較。另一種方法是在運行每個查詢之前刷新緩存,使用類似「ALTER SYSTEM FLUSH SHARED_POOL」和「ALTER SYSTEM FLUSH BUFFER_CACHE」。分享並享受。 – 2012-02-20 17:18:46

+0

因此,在每一行中,從3個FK中,2總是'0',只有​​1個實際參考。對? – 2012-02-20 22:53:53

回答

1

我會說這是因爲優化會分解選擇對抗,以選擇對他基本表的視圖。在第二種情況下,您不是將所有其他表的行聯合在一起,只是滿足該表的where子句的行,因此第二個查詢更快,因爲它必須通過更少的行。

相關問題