Обложка канала

Oracle Developer👨🏻‍💻

Все о разработке в СУБД "Oracle" SQL, PL/SQL, оптимизация, архитектура, сертификации и многое другое.

Oracle Developer👨🏻‍💻

4 года назад
Открыть в
Задача по оптимизации Полную постановку смотрите в посте вторника. Объяснение Типичная проблема при неправильном использовании механизмов СУБД. DBA очень часто негодуют по этому поводу. Итак, поехали разбирать. 1️⃣ Представление v$sqlarea показывает все выполнявшиеся запросы в БД (parent-курсоры). 2️⃣ Каждый запрос имеет свой sql_id (уникальный номер), hash_value (хэш от текста запроса) и др. 3️⃣ Как только СУБД начинает выполнять запрос, происходит его парсинг. В том числе, берется hash от текста запроса и сравнивается с тем, что уже есть в SGA в кэше запросов. Если запрос не найден, то производится жесткий разбор (hard parse). В итоге, разобранный запрос помещается в кэш запросов. Поменяете регистр одной буквы в запросе - это будет новый запрос и новый hard parse со всеми сопутствующими расходами. Следующие запросы, с точки зрения БД, разные.
select * from tab1 where id = 1;
select * from tab1 where id = 2;
Для каждого будет сгенерирован свой sql_id, свой план(возможно), будут помещены в кэш-запросов и т.п. множество накладных расходов. 4️⃣ Для решения подобной ситуации используются переменные связывания (bind vars). Вместо жестко заданного литерала (1, 2…) используется подстановка значения:
select * from tab1 where id = :var;
теперь в var можно подставлять значения 1, 2…и т.д. Не будет hard parse при подстановке значений. Не забивается кэш-запросов, DBA довольны. Том Кайт в своей книге “Oracle для профессионалов” буквально на первых же страницах пишет про связные переменные. Это было теоретическое введение. Перейдем к нашему примеру. Некое приложение соединяющееся c БД под пользователем ONE_C выполняло однотипный запрос аж 11166 раз (см. скриншоты ⬆️). Текст запросов отличается ровно в одной детали - использование разных ID в предикате (where t1…. = число). Да, из задания это не совсем очевидно. Поскольку в текстовом виде это абсолютно разные запросы, бедная СУБД выполнила аж 11166 раза hard pars забив кэш-запросов. Решение простое. Использовать переменную связывания в предикате, в которую подставлять конкретное значение.
select ... where t1… = :id
будет выполнен 1 раз hard parse и всё. ⚠️ Не надо нагружать СУБД бесполезной никому не нужной нагрузкой К сожалению, в рассматриваемой БД таких запросов не мало. Нужно явно править приложение 🛠 Этим грешат начинающие DBD, разработчики, пишущие на других языках, выполняющие запросы к СУБД Oracle. Уровень задачи легкий, т.к. это должен знать каждый кто использует СУБД Oracle. Это основы. На курсе по оптимизации будем разбирать множество интересных кейсов 😉 Обсудить в чатике #оптимизация #решениезадачи