Oracle otimize SELECT FOR UPDATE, у которых нет записей? - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть хранимая процедура, как показано ниже. У меня есть некоторые признаки того, что SELECT имеет только 15% случаев, когда существует идентификатор. Я вижу, что ОБНОВЛЕНИЯ выполняются только в те 15% случаев. Oracle как-то оптимизирует это?

BEGIN
        SELECT ID
        FROM Sessions
        WHERE ID = idt FOR UPDATE;

        UPDATE Sessions
        SET Expire = SYS_EXTRACT_UTC(SYSTIMESTAMP) + 1/288
        WHERE ID = idt

        COMMIT;
END;

1 Ответ

0 голосов
/ 19 апреля 2020

Краткий ответ - «Нет».
Oracle не делает никаких прогнозов относительно данных, которые сохранились в таблицах БД.
Это не детерминировано c вещь.
Единственное, что Oracle do for you - это мягкий анализ ваших SQL -s.

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

Если вы используете SELECT INTO простую скалярную переменную, тогда вы получите NO DATA FOUND исключение, и UPDATE не последует.
Если вы используйте объем в коллекцию и IN (ВЫБРАТЬ ИЗ ТАБЛИЦЫ (моя коллекция)) тогда у вас нет исключений и нет ОБНОВЛЕНИЙ .

Несколько советов по производительности:

  1. Может быть, вы хотите обработать много сеансов?
    В этом случае вы можете захотеть использовать массовые операции , например:
SELECT id BULK COLLECT INTO col_sessions_id from SESSIONS WHERE ...
FOR UPDATE

, а затем

  FORALL i IN col_sessions_id.first .. col_sessions_id.last
  UPDATE SESSIONS SET ... WHERE ID = col_sessions_id(i)

Когда вы используете ДЛЯ ОБНОВЛЕНИЯ без квалификаторов, вы можете получить зависание .
Без NOWAIT или явное WAIT предложение будет ждать, пока не будет получена блокировка.
Вы действительно этого хотите? Может быть, вам нужно вместо этого использовать NOWAIT или SKIP LOCKED вместо этого?
В высоконагруженных производственных случаях этот шаблон очень часто используется.
Конечно, вы должны обрабатывать исключения и корректировать ваши business logi c.

Использовать прямой доступ к строкам после выбора ДЛЯ ОБНОВЛЕНИЯ .
Помните, что вы можете выбрать ROWID вместо ID и использовать их позже для обновления.
Если вы передадите ROWID в предложение WHERE, то Oracle сделает вас DML очень быстрым, даже не используя индексы .
См. Простой ROWID пример здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...