Главная страница
Навигация по странице:

  • Сокращение вычислений при локализации объектов доступа

  • Отказ от повторных вычислений выражений

  • Оптимизация вычисления составного логического выражения

  • Возможность использовать индекс для доступа к строкам таблицы

  • Транзакции и блокировки

  • Оптимизации. Транзакции и блокировки. Оптимизации. Транзакции и блокировки


    Скачать 22.04 Kb.
    НазваниеОптимизации. Транзакции и блокировки
    Дата13.12.2021
    Размер22.04 Kb.
    Формат файлаdocx
    Имя файлаОптимизации. Транзакции и блокировки.docx
    ТипДокументы
    #301828

    Оптимизации. Транзакции и блокировки
    Oracle при формировании плана обработки поступившего запроса пытается переформулировать запрос в более выгодный для вычислений вид. При этом используются шаблоны равносильных преобразований, наличие вспомогательных структур БД и статистика объектов хранения. Сверх этого Oracle дает такие средства влияния на схему вычисления, как подсказки оптимизатору, особые параметры СУБД и особые конфигурации структур хранения объектов.

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

    Сокращение вычислений при локализации объектов доступа

    Полное указание имен объектов в запросе пусть незначительно, но сокращает время разбора. Например, есть два запроса:

    SELECT emp.ename FROM scott.emp;

    SELECT ename FROM emp;

    Второй имеет предпосылки обрабатываться дольше, так как при разборе запроса требует дополнительной работы по уточнению принадлежности таблицы схеме и столбца таблице. Заметьте к тому же, что, строго говоря, эти предложения не равносильны: при разборе второго может оказаться, что таблица EMP не принадлежит пользователю SCOTT (если запрос выдавался другим пользователем, имеющим одноименную таблицу, или если переменная сеанса CURRENT_SCHEMA имела значение, отличное от SCOTT).

    Отказ от повторных вычислений выражений

    В некоторых случаях формулировка запроса позволяет отказаться от повторного вычисления выражений. Примерами могут служить логические выражения BETWEEN и IN. Например, формулировка условного выражения

    ( sal + comm ) BETWEEN 1000 AND 2000

    способна обрабатываться эффективнее равносильной формулировки

    ( sal + comm >= 1000 ) AND ( sal + comm <= 2000 )

    Ответ на вопрос, будет ли первая формулировка действительно обрабатываться быстрее, зависит от сложности выражения. В данном случае подвыражение ( SAL + COMM ) достаточно просто, чтобы при построении плана, на этапе анализа формулировки, оптимизатор заметил, что во втором случае подвыражение повторяется, и фактически вычислял бы его однократно. Однако если бы вместо этого подвыражения стояла более сложная конструкция или если бы подвыражение содержало бы обращение к функции пользователя (все аспекты вычисления которой оптимизатору неизвестны), формулировку условного выражения через BETWEEN следовало бы признать более выгодной с вычислительной точки зрения. (Другие выгоды от BETWEEN — в надежности кода, из-за однократности записи выражения в запросе и в возможности задействовать в плане вычисления индекс, когда таковой имеется).

    Аналогичные рассуждения обосновывают выгоду от использования для построения условных выражений операторов IN или = ANY перед употреблением цепочек сравнения, составленных с помощью OR, и выгоду от ссылки на имя столбца, данное во фразе SELECT, перед воспроизведением выражения в другой фразе. Так, возвращаясь к одному из примеров выше, предпочтение следует отдать формулировке

    SELECT job, AVG ( sal ) avgsal FROM emp

    GROUP BY job

    ORDER BY avgsal

    ;

    перед формулировкой

    SELECT job, AVG ( sal ) FROM emp

    GROUP BY job

    ORDER BY AVG ( sal )

    ;

    Опять-таки, что касается вычислений, то для этого простого случая обе формулировки скорее всего приведут к одному общему сценарию обработки (это не совсем просто проверить), но когда вместо AVG ( SAL ) будет стоять более сложное выражение или оно будет содержать обращение к функции пользователя, бесспорно предпочтительней окажется формулировка первого типа.

    Оптимизация вычисления составного логического выражения

    Логические выражения, составленные цепочками с помощью связок OR или AND, при отсутствии у Oracle информации о сложности вычисления подвыражений вычисляются во вполне определенном направлении. Это обстоятельство можно использовать для размещения элементов цепочек, наиболее вероятно дающих TRUE или же FALSE в соответствующих концах цепочки.

    При просмотре сотрудников выражение

    ( sal > 1000 ) OR ( mgr IS NULL )

    будет вычисляться скорее, чем

    ( mgr IS NULL ) OR ( sal > 1000 )

    Это объясняется тем, что цепочка, построенная с помощью связок OR, вычисляется слева направо, а сотрудников с зарплатой более 1000 — больше, чем "президентов". Мизерная в данном случае разница может оказаться заметной на вычислительно более сложных выражениях.

    Переформулировка для сокращения объема обрабатываемых строк

    Перестановка фильтров строк способна сократить объем обработки. Так, предложение SELECT с фразой HAVING иногда можно переформулировать в содержательно равносильное, но вычислительно более эффективное за счет перенесения отбора строк из фразы HAVING во фразу WHERE. Вот пример запроса на количество разных сотрудников по специальностям, помимо клерков:

    SELECT job, COUNT ( * )

    FROM emp

    GROUP BY job

    HAVING job <> 'CLERK'

    ;

    Из сказанного ранее следует, что логическая последовательность действий по вычислению результата на этот запрос будет следующей:

    отбор строк по условию WHERE;

    разбиение строк на группы по условию GROUP BY;

    вычисление сверток (агрегатов) по каждой группе;

    отбор требуемых групп по условию HAVING.

    Памятуя логический порядок вычислений, объем вычислений затратной группировки можно сократить, переписав запрос в виде

    SELECT job, COUNT ( * )

    FROM emp

    WHERE job <> 'CLERK'

    GROUP BY job

    ;

    Некоторые специалисты вовсе дают рекомендацию избегать отсева групп фразой HAVING.

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

    SELECT e.ename, d.dname

    FROM emp e

    INNER JOIN dept d

    USING ( deptno )

    WHERE e.job <> 'SALESMAN'

    ;

    SELECT e.ename, d.dname

    FROM

    ( SELECT * FROM emp WHERE job <> 'SALESMAN' ) e

    INNER JOIN

    dept d

    USING

    ( deptno )

    ;

    В то же время не следует недооценивать оптимизатор Oracle: для двух последних запросов (пусть и не самых сложных) он дает одинаковый план исполнения, так что выбор одного из них становится всего делом предпочтения программиста.

    Возможность использовать индекс для доступа к строкам таблицы

    Хотя доступ к строкам таблицы по индексу не гарантирует высокую скорость (а иногда приводит даже к замедлению), часто он оказывается оправдан. Но решению СУБД употребить существующий индекс может, помимо прочего, препятствовать формулировка условного выражения. Например, в случае указания поля, соответствующего индексированному обычным индексом (древовидным и без функционального преобразования ключа) столбцу, в качестве параметра для функции СУБД откажется от использования индекса:

    SELECT empno FROM emp WHERE TRUNC ( empno ) = 7369;

    СУБД может воспользоваться индексом (если сочтет целесообразным), только если индексированное поле присутствует в одной из частей сравнения без каких-либо преобразований:

    SELECT empno FROM emp WHERE empno >= 7369;

    но не в этом случае:

    SELECT empno FROM emp WHERE empno + 0 >= 7369;

    Oracle не будет также отказываться от использования индекса в сравнениях с помощью других операторов:

    empno BETWEEN 7000 AND 8000

    empno IN ( 7369, 7865, 8888 )

    empno = ANY ( 7369, 7865, 8888 )

    empno = ALL ( 7369, 7865, 8888 )

    В сравнении оператором LIKE СУБД сможет привлекать индекс только если в проверочной маске первый слева символ не является специальным:

    job LIKE 'SAL%'

    но не:

    job LIKE '_SAL%'

    Транзакции и блокировки

    Транзакции и блокировки есть механизм регулирования доступа к БД из приложений.

    Транзакция в SQL есть логическая последовательность операций DML по внесению изменений в БД, принимаемая или же отвергаемая СУБД в конечном итоге ("по завершению транзакции") в целом. В английском языке слово transaction обозначает единицу общения двух агентов (в нашем случае — программы и СУБД), завершающуюся оказанием взаимного воздействия друг на друга.

    Понятие транзакции в реляционной теории отсутствует и составляет самостоятельный по отношению к ней предмет изучения. В случае баз данных транзакции позволяют:

    восстанавливать данные при аварийном прекращении сеанса связи программы с СУБД ("единица восстановления");

    гарантировать целостное представление данных программе при одновременной работе с данными нескольких программ;

    гарантировать целостное хранение данных в БД при одновременной работе с ними нескольких программ.

    Широко известны общие требования к механизму транзакций ("свойства ACID"):

    атомарность: последовательность изменений в БД, поступающая из программы во время транзакции, принимается или отвергается по завершению транзакции целиком, как единое целое;

    согласованность: каждая транзакция переводит БД в новое согласованное состояние, при том что, пока она не завершена, согласованности может и не быть;

    изолированность: изменения в БД, совершаемые в рамках транзакции, станут видны другим транзакциям только после ее фиксации;

    долговечность: изменения в БД, совершенные в рамках транзакции, не могут пропасть из-за сбоев работы СУБД.

    Некоторые эксперты полагают, что требование согласованности для транзакций в БД, то есть соблюдение ограничений целостности, должно обеспечиваться на уровне не транзакции (как то допускают и стандарт SQL, и Oracle), а отдельного оператора DML. Получается, что выполнение этого требования механизмом тразнакций свидетельствует о недостаточности языка SQL для моделирования событий в предметной области. К сожалению это не единственная возможная претензия к языку.

    Стандарт SQL предлагает определенный перечень средств для управления транзакциями. Oracle не поддерживает их в полном объеме и в полной мере, однако средства для управления транзакциями в Oracle обладают свойствами ACID и достаточны для нужд большинства приложений.


    написать администратору сайта