2012-02-20 2 views
1

У меня есть два выбора на одном и том же представлении. One Select будет фильтроваться с помощью первичного ключа, другой select будет filterd для уникального индекса. Используемый вид сложный. Для выбора с основным ключом требуется приблизительно 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 раздельно быстро.

--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

+0

Чтобы расширить ответ на @ tbone, есть две вещи, которые вы можете чтобы помочь устранить эффекты буферизации. Один из них заключается в том, чтобы дважды запускать каждый запрос и использовать для сравнения только результаты второго прогона. Другой - очистить кеш, прежде чем запускать каждый запрос, используя что-то вроде «ALTER SYSTEM FLUSH SHARED_POOL» и «ALTER SYSTEM FLUSH BUFFER_CACHE». Поделитесь и наслаждайтесь. –

+0

Итак, в каждой строке, из 3 FK, 2 всегда '0', и только 1 имеет фактическую ссылку. Правильно? –

ответ

1

Я бы сказал, это потому, что оптимизатор будет разлагаться избранным против того, чтобы он выбирает против базовых таблиц. Во втором случае вы не объединяете все строки других таблиц, а только строки, удовлетворяющие предложению where для этой таблицы, поэтому второй запрос выполняется быстрее, потому что он должен проходить через меньшее количество строк.

Смежные вопросы