Улучшить производительность обновления в Oracle - PullRequest
0 голосов
/ 23 октября 2018

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

Примерно так:

ALTER TABLE TEMP_MEASURINGS ADD PRIMARY KEY (MEASURINGID)

ALTER TABLE TEMP_VALUES ADD PRIMARY KEY (<some_other_col>)

Две временные таблицы связаны датой и другим идентификатором, как видно из запроса.Теперь мне нужно обновить «measureid» в TEMP_VALUES на основе другой таблицы.

Можно ли как-нибудь ускорить выполнение этого запроса?

UPDATE TEMP_VALUES v 
SET v.MEASURINGID = 
(
    SELECT MEASURINGID 
    FROM TEMP_MEASURINGS m 
    WHERE m.MEASURDATE = v.MEASUREDATE 
    AND m.ORDERID = v.ORDERID
)

Таблицы должны быть сгенерированы первымипоэтому я не могу сделать вставку напрямую.

SELECT COUNT(*) FROM TEMP_VALUES ~ 6M

SELECT COUNT(*) FROM TEMP_MEASURINGS ~ 1,5M

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

Ваш запрос будет медленным, потому что обновляется так много строк.

Вы можете ускорить его с индексом на TEMP_MEASURINGS(MEASUREDATE, ORDERID, MEASURINGID).Это закрывающий индекс для подзапроса.Поиск должен быть быстрым.

Вы можете найти это быстрее, просто создав новую таблицу:

create new_temp_values as 
    select v.*, m.measuringid           
    from temp_values v left join
         temp_measurings m
         on v.measuredate = m.measuredate and v.orderid = m.orderid;

Здесь будет работать тот же индекс (вы можете настроить столбцы select, чтобычто вам действительно нужно).

Как правило, создание новой таблицы намного, намного быстрее, чем обновление всех или даже значительного числа строк в данной таблице.

0 голосов
/ 23 октября 2018

Вместо обновления всех записей вы можете обновить записи, которые существуют во временной таблице:

UPDATE TEMP_VALUES v 
    SET v.MEASURINGID = 
    (
        SELECT MEASURINGID 
        FROM TEMP_MEASURINGS m 
        WHERE m.MEASURDATE = v.MEASUREDATE 
        AND m.ORDERID = v.ORDERID
    )
    where 
    exists (select 1 from TEMP_VALUES ttt, TEMP_MEASURINGS ttm WHERE ttm.MEASURDATE = ttt.MEASUREDATE 
        AND ttm.ORDERID = ttt.ORDERID and ttt.ID = v.ID)
0 голосов
/ 23 октября 2018

Попробуйте слияние ниже для производительности:

MERGE TEMP_VALUES v
USING (SELECT MEASURINGID,
              MEASURDATE,
              ORDERID
       FROM TEMP_MEASURINGS) m
ON 
   m.MEASURDATE = v.MEASUREDATE 
   AND m.ORDERID = v.ORDERID
WHEN MATCHED THEN
       UPDATE
       SET v.MEASURINGID = m.MEASURINGID;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...