Лабораторная работа №2. 1. Оптимизация запросов к базе данных Цель работы. Изучить работу оптимизатора запросов, используемого в СУБД INFORMIX-Online. Теоретические аспекты. Порядок, в котором анализируются отношения, оказывает огромное влияние на скорость выполнения запроса. Сервер баз данных INFORMIX содержит специальную компоненту, которая называется оптимизатором. Задачей оптимизатора является повышение эффективности индивидуального запроса. Оптимизатор определяет всевозможные планы запросов, оценивает объем работы каждого плана (подсчитывает число анализируемых кортежей, число прочитанных дисковых страниц, число сетевых обращений) и выбирает для исполнения сервером план с наименьшей оценкой объема работ. Алгоритм оптимизации включает в себя как аналитические, так и эвристические процедуры, поэтому оценки носят вероятностный характер. Существует «высокий» и «низкий» уровни работы оптимизатора. Для управления уровнем оптимизации служит оператор SET OPTIMIZATION {HIGH I LOW}. По умолчанию используется SET OPTIMIZATION HIGH - высокий уровень оптимизации сервера баз данных. Алгоритм, соответствующий высокому уровню оптимизации, является достаточно сложным. Он исследует все разумные планы и выбирает лучший из альтернатив. Однако высокий уровень в случае больших соединений отношений может вызвать большие затраты выполнения запроса как по времени, так и по используемой памяти. Альтернативный алгоритм, вызываемый SET OPTIMIZATION LOW, исключает маловероятные стратегии соединения на ранних стадиях и поэтому сокращает время и ресурсы памяти, используемые при оптимизации. Однако, в этом случае, возможен риск, что не будет выбрана оптимальная стратегия, так как она была исключена на ранних стадиях алгоритма. Необходимый уровень оптимизации выбирается при экспериментальной работе разработчика с прикладной программой. При построении и анализе возможных планов запроса оптимизатор использует сводную информацию об отношениях из системного каталога, в состав которой входят: 1. Число кортежей в любом отношении, которое соответствует самому последнему результату специально выполненного SQL - оператора UPDATE STATISTICS. 2. Признаки ограничения уникальности на атрибуты отношения. 3. Информация об атрибутах, на которых построены индексы. Являются ли они убывающими, возрастающими, кластерными. Кластерный индекс используется для физической сортировки значений отношения в порядке, предписанном индексом. 4. Число страниц на диске, занятых кортежами отношения. 5. Глубина структуры B-дерева индекса для оценки глубины поиска. 6. Число страниц на диске, занятых элементами индекса. При соединении в запросе нескольких отношений оптимизатор осуществляет парное соединение отношений, выбирая лучшие планы соединения с точки зрения наименьшего объема работ. Лучшие планы оптимизатор использует для формирования всевозможных соединений двух отношений с третьим, выбирая при этом лучшие планы и так далее. Далее, если в запросе присутствует спецификатор ORDER BY или GROUP BY, а построенный план не вырабатывает результирующие кортежи в упорядоченной последовательности, то оптимизатор дополнительно строит временные индексы и добавляет объемы работ, связанные с сортировкой результата. Таким образом, оптимизатор строит план, который имеет наименьший объем работы и передает его на выполнение в главную часть сервера баз данных. Для того, чтобы проанализировать план запроса, построенный оптимизатором, необходимо использовать оператор SQL: SET EXPLAIN ON. Этот оператор устанавливает режим работы сервера с протоколированием планов выполнения SQL-запросов. Результат выполнения работы находится в некотором файле, при этом имя этого файла и его месторасположение зависит от операционной системы. Установка режима действует до вызова оператора: SET EXPLAIN OFF. Оптимизатор показывает оценку объема своих действий в условных единицах. Не всегда очевидно, почему оптимизатор выполнил запрос согласно построенному плану. Изменив запрос и сравнивая планы, можно сделать вывод о логике работы оптимизатора. Порядок выполнения работы: Задание 1. Установить режим работы сервера с протоколированием планов выполнения SQL-запросов: 1. Запустить SQL explorer, открыть свой алиас. 2. Включить режим журнализации запроса: набрать и выполнить команду «set explain on». 3. Выполнить все SQL-запросы по индивидуальному заданию, не закрывая текущего соединения с БД. Задание 2. Проанализировать планы запросов по заданию. Для просмотра результата выполнения работы оптимизатора необходимо открыть файл-протокол stud1.out, находящийся на сервере: Вся сеть/Microsoft windows network/pmi/serv3/sqexpln. Открыть файл-протокол выполнения запросов. 1. 2. Появившийся список запросов пролистать до конца и найти свои запросы (они записываются в конец файла). Для каждого из запросов выписать числовую оценку трудоемкости выполнения запроса Estimated Cost. Задание 3. Создать индексы к таблицам базы данных. Проанализировать, какие из таблиц нуждаются в создании индекса. Для создания индекса выполнить команду SQL: CREATE [UNIQUE] [CLUSTER] INDEX имя_индекса ON имя_таблицы (имя_атрибута_1, [ASC | DESC], …. имя_атрибута_k, [ASC | DESC]) Задание 4. Снова проанализировать планы запросов по заданию, учитывая созданные индексы. Находясь в SQL explorer, снова выполнить в нем все SQL-запросы по заданию. 1. 2. Просмотреть результаты выполнения работы оптимизатора. Убедиться, что при выполнении запроса действительно использовался индекс (наличие строки INDEX PATH). 3. Для каждого вновь выполненного запроса сравнить числовую оценку трудоемкости выполнения запроса Estimated Cost с той, которая была получена при выполнении соответствующего запроса до создания индексов. Задание 5. Модифицировать запросы по заданию таким образом, чтобы ускорить его выполнение и уменьшить его трудоемкость Estimated Cost. Задание 6. Снять режим протоколирования планов выполнения запросов. Находясь в SQL explorer, выключить режим журнализации запроса: набрать и выполнить команду set explain off. 2. Управление доступом пользователей к базам данных Цель работы. Приобрести навыки по предоставлению и отмене прав (привилегий) доступа к базам данных и таблицам. Теоретические аспекты. Для доступа пользователя к информации существуют привилегии (право) двух типов: доступ к базе данных и доступ к отношению. Каждая привилегия определяет те действия по манипулированию структурой и данными, которые доступны пользователю. После создания базы данных ее создатель или администратор базы данных предоставляет права на доступ другим пользователям. Все пользователи, имеющие доступ к базе данных, получают право на доступ к каждому ее отношению. Однако владелец базы данных может отменить право доступа пользователя к любому отношению, входящему в состав базы данных. Пользователь может обладать одной из трех привилегий доступа к базе данных: Ключевое слово Привилегия доступа к базе данных CONNECT Открытие базы данных, выполнение запросов и создание индексов для временных таблиц. RESOURCE Все привилегии Connect и дополнительно: создание, изменение постоянных таблиц и индексов. DBA Все права администратора базы данных. Назначение привилегий доступа к базе данных осуществляется c помощью оператора языка SQL GRANT, который имеет следующий синтаксис: GRANT {CONNECT | RESOURCE | DBA } TO {PUBLIC | список_пользователей}. Отмена привилегий – с помощью оператора языка SQL REVOKE: REVOKE {CONNECT | RESOURCE | DBA } FROM {PUBLIC | список_пользователей}. Слово «PUBLIC» используется для обозначения фразы «любого пользователя, имеющего привилегию Connect». Пользователь может обладать одним или сочетаниями нескольких привилегий доступа к отношениям. В следующей таблице представлены следующие привилегии: Ключевое слово Привилегия доступа к отношению Выбор кортежа из отношения (эта привилегия может быть ограничена определенными SELECT атрибутами в отношении). DELETE Удаление кортежа. INSERT Вставка кортежа. UPDATE Корректировка кортежа. INDEX Создание индексов на атрибутах отношения базы данных для пользователя, имеющего привилегию Resource. Создание индексов на атрибутах временного отношения для пользователя, имеющего привилегию Connect. Право на изменение отношения. ALTER В системном каталоге СУБД Informix существуют системные отношения, которые описывают структуру базы данных. Привилегии, предоставляемые на каждое отношение, фиксируются в системном отношении systabauth. Каждая запись этого отношения имеет ссылку на уникальный номер tabid, который однозначно идентифицирует кортеж в другом системном отношении systables, хранящем информацию об имени отношения и его уникальном номере. Для отображения привилегий, предоставленных на отношение с именем «сотрудник» можно выполнить следующий оператор SELECT: SELECT * FROM systabauth WHERE tabid = (SELECT tabid FROM systables WHERE tabname = “преподаватель”) Пример результата выполнения этого запроса представлен в виде следующей таблицы: Grantor Grantee Tabid Tabauth (кто) (кому) (на какое отношение) (какие права) USER USER1 101 su-i-x-- USER USER2 101 s--idx-- USER PUBLIC 101 s--i-x-- В данной таблице используются следующие обозначения привилегий: s – select; u – update; i – insert; d – delete; x – index. Перед тем, как сервер баз данных выполнит конкретный оператор для некоторого пользователя (например, delete) он выполнит запрос, аналогичный запросу, представленному выше. Если пользователь не является владельцем отношения и сервер не может найти для этого пользователя необходимые привилегии на отношение, то сервер отказывается выполнить требуемый оператор. Назначение привилегии осуществляется с помощью следующего оператора GRANT: GRANT привилегии_отношения ON имя_отношения TO {PUBLIC | список_пользователей} В составе привилегий доступа к отношению могут быть указаны один или несколько из перечисленных ниже привилегий: SELECT [(атрибут_1,…, атрибут_k)], INSERT, DELETE, ALTER, UPDATE [(атрибут_1,…, атрибут_k)], INDEX, ALL [PRIVILEGES]. Если в привилегиях SELECT и UPDATE указан перечень атрибутов, то это означает, что привилегии касаются только перечисленных атрибутов. В противном случае – всех атрибутов указанного отношения. Отобрать привилегии, которые даны пользователю, можно с помощью оператора REVOKE: REVOKE привилегии_отношения ON имя_отношения FROM {PUBLIC | список_пользователей} Замечание. При формулировании заданий были сделаны следующие предположения: имеются два пользователя с именами STUD1 и Informix; пользователь Informix создал базу данных BASE и соответственно обладает на нее всеми правами. Порядок выполнения работы: Задание 1. Установить право доступа CONNECT пользователю STUDn. 1. Войти как пользователь под своим именем STUDn. 2. Выбрать пункт “Query Language”. 3. Выбрать базу данных, созданную другим пользователем, с помощью меню SELECT DATABASE >>. Например, базу данных с именем BASE, созданную пользователем Informix. 4. Получив отказ в доступе, перейти к сессии пользователя Informix. 5. Выберите базу BASE и дайте право доступа CONNECT пользователю STUDn: GRANT CONNECT TO STUDn 6. Перейти к сессии STUDn и повторить попытку выбора базы данных BASE. 7. Выполнить любой запрос к базе данных BASE под пользователем STUDn. Задание 2. Дать право доступа RESOURCE пользователю STUDn. 1. Попытаться изменить структуру выбранной таблицы из базы данных BASE под пользователем STUDn . 2. Получив отказ в доступе, перейти к сессии пользователя Informix. 3. Выбрать базу BASE и дать право доступа RESOURCE пользователю STUDn к базе BASE: GRANT RESOURCE TO STUDn 4. Изменить структуру выбранной таблицы пользователем STUDn и сохранить ее в базе данных. Задание 3. Отменить привилегию SELECT пользователю STUDn. 1. Перейти к сессии пользователя Informix и в ней выбрать какую-либо таблицу. Отобрать привилегию SELECT на выбранную таблицу у пользователя STUDn: REVOKE SELECT ON имя_таблицы FROM STUDn 2. Перейти к сессии STUDn и попытаться исполнить SELECT по выбранной таблице. 3. Перейти к сессии пользователя Informix. Дать привилегию исполнения запроса SELECT на таблицу пользователю STUDn: GRANT SELECT ON имя_таблицы TO STUDn 4. Выполнить SELECT по выбранной таблице пользователем STUDn. Задание 4. Отменить все привилегии пользователя STUDn. Для этого необходимо перейти к сессии пользователя Informix, выбрать базу данных BASE и выполнить команду: REVOKE CONNECT FROM STUDn. Задание 5. Отобразить привилегии, предоставленные на какую-либо из таблиц с именем «ИМЯ». Для отображения привилегий на эту таблицу необходимо выполнить следующий SQL – оператор: SELECT * FROM systabauth WHERE tabid = (SELECT tabid FROM systables WHERE tabname = “ИМЯ”) Описание результата выполнения запроса можно посмотреть в работе [1].