Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Базы данных. Лекции по курсу. В 4 частях. Ч.1. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
06.09.2026
Размер:
1 Мб
Скачать
Сведения о плане выполнения запроса могут быть доступны разра­ботчику, и анализ сгенерированного СУБД плана выполнения запроса позволяет:
понять, как СУБД будет исполнять запрос;
найти «узкие» места в запросе, максимально влияющие на время
его выполнения.
Для получения плана выполнения запроса можно использовать SQL-операторы
explain QUERY_TEXT
explain analyze QUERY_TEXT
или
или воспользоваться клавишами «F7» или «Shift+F7».
SQL-запрос для получения плана выполнения исходного запроса (рис. 5):
EXPLAIN ANALYZE
select p.country, count (*) books_count
from books b, publishers p
where b.publisher_id = p.id and b.genre = 'Жанр 45'
group by p.country order by 2 desc
Рис. 5. План выполнения SQL-запроса
41
Из рис. 5 видно, что стоимость плана запроса в некоторых аб­страктных единицах составляет 42 978, а время выполнения запроса ~625 мс. На рис. 6 схематично показаны операции, выполняемые при реализации запроса: чтение исходных таблиц, соединение, вычисление агрегированных значений и сортировка.
Рис. 6. Операции при выполнении SQL-запроса
Как можно оптимизировать этот запрос?
1. Использование индексирования. Индекс – объект базы данных, создаваемый с целью повышения скорости поиска данных. Подробно об этом будет рассказано в теме «Физическое проектирование». Ин­декс позволяет искать строки, удовлетворяющие заданному критерию поиска.
Создадим индекс для столбца
genre таблицы books:
create index on books (genre).
План выполнения SQL-запроса после создания индекса показан на
рис. 7. Из него видно, что стоимость плана запроса уменьшилась до
6729 единиц, а время выполнения запроса сократилось в 40 раз, до
13.6 мс.
На рис. 8 схематично показаны операции, выполняемые при реали­зации запроса. К перечисленным ранее операциям добавилась опера­ция индексирования, которая и обеспечила
существенное сокращение
времени выполнения запроса.
Таким образом, можно сделать вывод, что, анализируя план вы­полнения запроса, можно оптимизировать SQL-запрос, добившись требуемых характеристик.
42
Рис. 7. План выполнения SQL-запроса с индексированием
Рис. 8. Операции при выполнении SQL-запроса с индексированием
2. Порядок соединения таблиц. Как отмечалось ранее, на скорость выполнения существенно влияет порядок соединения таблиц. Перепи­шем SQL-запрос, изменив порядок соединения. Исходный запрос:
select p.country, count (*) books_count
from books b, publishers p where b.publisher_id = p.id and b.genre = 'Жанр 45' group by p.country order by 2 desc
43
Измененный запрос с новым порядком индексирования:
select p.country, sum (b.cnt) books_count
from publishers p inner join
(select publisher_id, count (*) cnt
from books where genre = 'Жанр 45' group by publisher_id
) b
on b.publisher_id = p.id
group by p.country order by 2 desc
План выполнения нового SQL-запроса изменился (рис. 9).
Рис. 9. План выполнения SQL-запроса с измененным порядком соединения
Из рисунка видно, что стоимость плана запроса уменьшилась (хотя
и незначительно) до 6715 единиц, а время выполнения запроса умень-
44
шилось до 10.9 мс. На рис. 10 схематично показаны операции, выпол­няемые при реализации нового запроса: чтение исходных таблиц, со­единение, вычисление агрегированных значений и сортировка.
Рис. 10. Операции при выполнении SQL-запроса с измененным порядком
соединения
3. Фрагментация таблиц. Еще один прием – фрагментация. Пусть нам необходимо выполнить запрос «Получить все данные о книгах, изданных в стране "Страна 5" за заданный период, отсортировав их по времени издания».
SQL-запрос, решающий такую задачу, может иметь вид:
select b.* from books b, publishers p where b.publisher_id = p.id and b.publication_date between '2000-01-01' and '2000-12-31' and p.country = 'Страна 5' order by b.publication_date
План выполнения SQL-запроса показан на рис. 11, а последова­тельность выполняемых операция в этом плане выполнения запроса – на рис. 12. Из рис. 11 видно, что стоимость плана запроса составляет 43 353 единиц, а время выполнения запроса 578 мс. Среди операций на рис. 12 присутствуют операции чтения таблиц, ограничения, соедине­ния и сортировки. Отметим, что при выполнении данного SQL-
запроса
индексирование отсутствует.
45
Рис. 11. План выполнения SQL-запроса
Рис. 12. Операции при выполнении SQL-запроса
Выполним индексирование таблиц publishers и books по ключевым полям.
create index on publishers (country)
create index on books
(publication_date)
Индексирование изменит план выполнения SQL-запроса (рис. 13), сделает его более оптимальным. Изменится и состав операций
(рис. 14). Все это скажется на стоимости плана выполнения запроса (9813 единиц), и времени его выполнения (10.4 мс).
46
Рис. 13. План выполнения SQL-запроса с индексированием
Рис. 14. Операции при выполнении SQL-запроса с индексированием
Выполним горизонтальную фрагментацию таблицы books по стра­нам, в которых издавались книги:
create table books_country_5 as select * from books
47
where publisher_id in (select id from publishers
where country = 'Страна
5')
Аналогичные запросы выполним для стран "Страна 1", …"Страна 10".
При выполнении такой серии SQL-запросов создаются таблицы
books_country_1, …books_country_10.
Перепишем теперь SQL-запрос таким образом, чтобы он работал с фрагментированной таблицей
books.
Исходный SQL-запрос:
select b.*
from books b, publishers p
where b.publisher_id = p.id
and b.publication_date between '2000-01-01' and '2000-12-31'
and p.country = 'Страна 5'
order by b.publication_date
SQL-запрос с фрагментированной таблицей books:
select b.* from books_country_5 b
where b.publication_date between '2000-01-01' and '2000-12-31'
order by b.publication_date
План выполнения SQL-запроса с фрагментированной таблицей
books показан на рис. 15.
Рис. 15. План выполнения SQL-запроса с фрагментированной таблицей books
48
Стоимость плана выполнения запроса составляет 4318 единиц, время выполнения SQL-запроса – 13.1 мс. Среди операций в плане запроса присутствуют операции чтения таблицы, ограничения и сорти­ровки (рис. 16).
Рис. 16. Операции при выполнении SQL-запроса
с фрагментированной таблицей books
Выполним индексирование созданных таблиц и вновь построим план выполнения запроса (рис. 17):
create index on books_country_5 (publication_date)
Рис. 17. План выполнения SQL-запроса с фрагментированной таблицей books
и индексированием
Стоимость плана уменьшилась до 956 единиц, а время выполнения SQL-запроса сократилось до 1.1 мс. Операции в плане запроса показа­ны на рис. 18.
49
Рис. 18. Операции при выполнении SQL-запроса с фрагментированной
таблицей books и индексированием
Результаты оптимизации для разных вариантов SQL-запроса сведе­ны в табл. 2.
Таблица 2
с 01.01.2000 по 31.12.2000
Типы запросов
Исходный запрос 43 353 578 мс Исходный запрос с индексированием 9 813 10.4 мс Запрос с фрагментацией 4 319 13.1 мс
Стоимость
плана
Время
выполнения
Запрос с фрагментацией и индексиро­ванием
957 1.1 мс
Можно говорить и о вертикальной фрагментации. Рассмотрим за­дачу «Вывести названия всех издательств и количество книг, изданных в каждом из них». SQL-запрос, решающий задачу, можно записать следующим образом:
select p.name, b.cnt
from publishers p,
(select publisher_id, count (*) cnt
from books
group by publisher_id
) b
where b.publisher_id = p.id
План выполнения SQL-запроса показан на рис. 19, а последова­тельность выполняемых операция в этом плане – на рис. 20.
50
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]