2016-11-29 3 views
0

Я пытаюсь перейти иерархическую структуру на оракуле, и у меня возникают серьезные проблемы с производительностью. Это мой код:Использование поля в обновлении резко замедляет запрос

UPDATE {table} t1 
SET (t1.{column2}) = (
    SELECT max(t2.{date}) FROM {table2} t2 
    WHERE t2.{column} in(
     SELECT t3.{column} 
     FROM {table3} t3 
     START WITH t3.{columnt3} = 'blablabla' 
     CONNECT BY t3.{columnt3} = PRIOR t3.{column} 
     )) 
WHERE t1.{column1} = 'blablabla' 

Этот код работает и работает в рамках одной секунды. Теперь, заменив первый 'blablabla' с t1. {Column1} (эти два эквивалента) приводит к более чем одной минуте времени выполнения. код выглядит то, как это:

UPDATE {table} t1 
SET (t1.{column2}) = (
    SELECT max(t2.{date}) FROM {table2} t2 
    WHERE t2.{column} in(
     SELECT t3.{column} 
     FROM {table3} t3 
     START WITH t3.{columnt3} = t1.{column1} 
     CONNECT BY t3.{columnt3} = PRIOR t3.{column} 
     )) 
WHERE t1.{column1} = 'blablabla' 

Кто-нибудь знает причину этой странной проблемы?

Edit: Вот объяснить план для верхней (рабочее) запроса: first explain plan

А вот один для второго (сломанного) запроса: second explain plan

Как вам можно увидеть, время выполнения просто взрывается путем поиска по t2, очень большой таблице. Но почему это происходит? и есть ли причина, почему это происходит?

Edit 2:

Может быть, оригинал код помогает немного больше:

UPDATE tmp_obsolete t1 
SET (liefertermin) = (
    SELECT max(versand_termin) FROM ropd7.pkvp 
    WHERE artikel_nr in(
     SELECT pstp.artikel_nr 
     FROM ropd7.pstp 
     START WITH pstp.komponenten_art_nr = 'XX.XX.XX.XX.XX' 
     CONNECT BY pstp.komponenten_art_nr = PRIOR pstp.artikel_nr 
     )) 
WHERE t1.artikel_nr = 'XX.XX.XX.XX.XX'; 


UPDATE tmp_obsolete t1 
SET (liefertermin) = (
    SELECT max(versand_termin) FROM ropd7.pkvp 
    WHERE artikel_nr in(
     SELECT pstp.artikel_nr 
     FROM ropd7.pstp 
     START WITH pstp.komponenten_art_nr = t1.artikel_nr 
     CONNECT BY pstp.komponenten_art_nr = PRIOR pstp.artikel_nr 
     )) 
WHERE t1.artikel_nr = 'XX.XX.XX.XX.XX'; 
+1

Вы сравнили планы выполнения? –

+2

'CONNECT BY t3. {Columnt3} = t3. {Column}' эта строка правильная? Обычно вы ожидаете увидеть ключевое слово PRIOR где-то там. То есть 'CONNECT BY PRIOR t3. {Columnt3} = t3. {Column}' или 'CONNECT BY t3. {Columnt3} = PRIOR t3. {Column}', в зависимости от того, какая ваша иерархия определена – Boneist

+0

@WernfriedDomscheit: да я их сравнивал и более поздний просто взорвался. Но это не очень помогает, потому что я все еще не могу объяснить, почему это происходит. –

ответ

0

я не нашел хорошее решение, чтобы сделать это запрос выполнялся эффективно, поэтому я попытался использовать простую PL/SQL-функцию, которая возвращает max (date) при предоставлении параметра. И это работает очень хорошо. Переход через ~ 1000 записей до 400 мс.

Спасибо всем за помощь.

0

ли переписывание помощь запроса:

UPDATE {table} t1 
SET (t1.{column2}) = (
    SELECT max(t2.{date}) 
     FROM {table2} t2 
     JOIN {table3} t3 
     ON t2.{column} = t3.{column} 
    START WITH t3.{columnt3} = t1.{column1} 
    CONNECT BY t3.{columnt3} = PRIOR t3.{column}) 
WHERE t1.{column1} = 'blablabl'; 
+0

Благодарим вас за ответ, но у меня все еще есть полный доступ к таблице на t2, поэтому ему все равно требуется возраст. –

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