2012-02-20 102 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子句的行,因此第二个查询更快,因为它必须通过更少的行。

相关问题