2017-02-10 14 views
0

У меня есть таблица T с 500 000 записей. Эта таблица является иерархической таблицей. Моя цель - обновить таблицу, присоединившись к той же таблице на основе некоторого условия для отношений родитель-потомок. . Запрос на обновление занимает очень много времени, потому что количество строк действительно велико. Я создал уникальный индекс в столбце, который помогает идентифицировать строки для обновления (знаковые x и Y). После создания индекса стоимость уменьшилась, но все же запрос выполняет намного медленнее.Настройка Oracle Sql с индексом

Этот формат мой запрос

update T 
set a1, b1 
= (select T.parent.a1, T.parent.b1 
from T T.paremt, T T.child 
where T.parent.id = T.child.Parent_id 
and T.X = T.child.X 
and T.Y = T.child.Y 

после создания индекса план выполнения показывает, что делает просмотр индекса для CRS.PARENT, но будет для полного сканирования таблицы для для CRS.CHILD, а также во время обновления в результате запрос навсегда завершается.

Пожалуйста, предложите какие-либо советы или рекомендации, чтобы решить эту проблему

+1

Запустите 'EXPLAIN PLAN FOR update T .... (resto uf your query) ....', затем 'SELECT * FROM table (DBMS_XPLAN.Display)', затем скопируйте результат последнего запроса (в виде текста !!! - не bitmap !!!) и добавьте его к вопросу. Подробнее об команде команды plan можно найти здесь: https://docs.oracle.com/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009 – krokodilko

ответ

3

Вы обновляете все 500000 строк, поэтому индекс является плохой идеей. 500 000 запросов индекса потребуют гораздо больше времени, чем нужно.

Вы бы лучше служили с помощью инструкции MERGE.

Трудно точно сказать, что ваша структура таблицы, но это будет выглядеть примерно так, предполагая, что X и Y являются столбцы первичного ключа в T (... может быть неправильно об этом):

MERGE INTO T 
USING (SELECT TC.X, 
       TC.Y, 
       TP.A1, 
       TP.A2 
     FROM T TC 
     INNER JOIN T TP ON TP.ID = TC.PARENT_ID) U 
ON (T.X = U.X AND T.Y = U.Y) 
WHEN MATCHED THEN UPDATE SET T.A1 = U.A1, 
          T.A2 = U.A2; 
+0

Если вы обновляете все 500 000, возможно, создайте таблицу и сделайте INSERT ... AS SELECT ... – BobC

+0

@BobC Возможно, вы правы, но обновление двух столбцов в таблице строк 500k не должно занять слишком много времени. Я не думаю, что я бы представил сложность DDL в этом процессе, если бы я не был обязан максимизировать производительность. –

+0

Вопрос в том, что было опубликовано было о производительности, которая является моей областью знаний. Вы правы в том, что выполнение обновления может быть «достаточно хорошим», но я хотел хотя бы показать, что отличная производительность может быть достигнута. DDL/DML не будет таким сложным. Однако это открывает возможность прямой загрузки пути (с помощью подсказки APPEND) и параллелизма. Выполнение преобразования с модификацией с прямой загрузкой пути также устранит большую часть накладных расходов для отмены и повтора. Опять же, я просто хочу, чтобы читатели сообщения поняли, что возможно. – BobC