- •1.2.2Типы представлений — до 5 мин.
- •1.2.3Создание представлений — до 25 мин.
- •1.2.4Использование представлений — до 10 мин.
- •1.2.5Изменение и удаление представлений — до 5 мин.
- •1.2.6Индексированные представления — до 5 мин.
- •2.2.2Создание хранимых процедур — до 15 мин.
- •2.2.3Использование параметров — до 15 мин.
- •2.2.4Использование локальных переменных внутри хранимой процедуры — до 15 мин.
- •2.2.5Использование return для возвращаемых значений — до 10 мин.
- •2.2.6Использование select для возвращаемых значений — до 10 мин.
- •2.2.7Управление хранимыми процедурами с помощью t-sql — до 10 мин.
- •3.2.2Когда использовать триггеры —до 10 мин.
- •3.2.3Создание триггеров — до 10 мин.
- •3.2.4Создание триггера типа delete — до 10 мин.
- •3.2.5Создание триггера типа insert — до 5 мин.
- •3.2.6Создание триггера типа update — до 10 мин.
- •3.2.7Создание триггера instead of — до 10 мин.
- •3.2.8Использование триггеров after — до 5 мин.
- •3.2.9Использование вложенных триггеров — до 10 мин.
- •3.2.10Управление триггерами с помощью операторов t-sql — до 5 мин.
- •4.2.2Уровни изолированности — до 10 мин.
- •4.2.3Поведение параллельных транзакций — до 10 мин.
- •4.2.4Режимы транзакций — до 20 мин.
- •4.2.5Вложенные транзакции — до 15 мин.
- •4.2.6Откаты транзакций — до 15 мин.
- •4.2.7Точки сохранения — до 10 мин.
- •5.2.2Уровни блокировок — до 15 мин.
- •5.2.3Режимы блокировки — до 20 мин.
- •5.2.4Блокирование и взаимоблокировки — до 20 мин.
- •5.2.5Подсказки блокировки — до 20 мин.
- •6.2.2Логическая оптимизация запросов — до 20 мин.
- •6.2.3Оптимизация плана исполнения запроса — до 15 мин.
- •6.2.4Подсказки оптимизатору запросов — до 15 мин.
- •6.2.5Оптимизация с использованием sql Server 2000 Index Tuning Wizard и sql Server 2005 Database Tuning Advisor — до 30 мин.
- •7.2.2Режимы аутентификации — до 15 мин.
- •7.2.3Учетные записи и пользователи — до 20 мин.
- •7.2.4Администрирование полномочий доступа к базам данных — до 20 мин.
- •7.2.5Администрирование ролей баз данных — до 10 мин.
- •7.2.6Делегирование учетной записи безопасности — до 15 мин.
- •8.2.2Внедрение sql кода (sql Injection) — до 20 мин.
- •8.2.3Защита sql Server в Интернет — до 20 мин.
- •8.2.4Пример организации системы безопасности приложений — до 40 мин.
- •9.2.2Журнальное протоколирование в sql Server — до 20 мин.
- •9.2.3Контрольные точки — до 15 мин.
- •9.2.4Методы резервного копирования — до 25 мин.
- •10.2.2Слежение за резервным копированием — до 10 мин.
- •10.2.3Планирование резервного копирования — до 25 мин.
5.2.4Блокирование и взаимоблокировки — до 20 мин.
Блокирование (blocking) и взаимоблокировки (deadlock) – это две дополнительные проблемы, которые могут возникать при одновременно выполняемых транзакциях. Они могут приводить к серьезным проблемам системы, а также могут замедлять и даже останавливать работу. Эти проблемы могут разрешаться в приложении, или SQL Server постарается сделать все возможное для их разрешения; они будут описаны здесь только для того, чтобы вы представляли их себе и понимали используемые концепции. Обход и разрешение проблем блокирования и взаимоблокировки являются обязанностью программиста.
Блокирование возникает в том случае, когда одна транзакция владеет блокировкой по какому-либо ресурсу, а второй транзакции требуется конфликтный тип блокировки по этому ресурсу. Вторая транзакция должна ждать, пока первая транзакция освободит свою блокировку; иными словами, она блокирована первой транзакцией. Проблема блокирования обычно возникает, когда какая-либо транзакция захватывает блокировку на длительный период времени, что приводит к цепочке блокированных транзакций, ожидающих окончания других транзакций, чтобы получить необходимые им блокировки; это состояние называют цепным блокированием. На рисунке 10.1 показан пример цепного блокирования.
Взаимоблокировка отличается от блокированной транзакции в том, что взаимоблокировка возникает в случае двух блокированных транзакций, ожидающих друг друга. Например, предположим, что одна транзакция владеет монопольной блокировкой по Таблице 1, а вторая владеет монопольной блокировкой по Таблице 2. Прежде чем будет освобождена любая монопольная блокировка, первой транзакции требуется блокировка по Таблице 2 и второй транзакции – требуется блокировка по Таблице 1. Теперь каждая транзакция ждет, пока другая транзакция освободит свою монопольную блокировку, но ни одна из транзакций не сделает этого, пока не будет выполнено фиксирование или откат для завершения соответствующей транзакции. Ни одна из транзакций не может завершиться, поскольку для продолжения работы ей требуется блокировка, которой владеет другая транзакция, – ситуация взаимоблокировки! Этот сценарий показан на рисунке 10.2. При возникновении взаимоблокировки SQL Server прекращает одну из транзакций, и ее требуется запустить заново.
Рисунок 10.1 — Цепное блокирование
Рисунок 10.2. Взаимоблокировка
5.2.5Подсказки блокировки — до 20 мин.
Подсказки блокировки – это ключевые слова T-SQL, которые можно использовать с операторами SELECT, INSERT, UPDATE и DELETE, чтобы задать для SQL Server использование предпочтительного типа блокировки на уровне таблицы для определенного оператора. Вы можете использовать подсказки блокировки для переопределения принятого по умолчанию уровня изолированности. Вам следует использовать этот метод только в случае абсолютной необходимости, поскольку ваша неаккуратность может привести к блокированию или взаимоблокировкам.
Рассмотрим ситуацию, где может оказаться полезным использование подсказок блокировки. Предположим, что вы используете для всех транзакций принятый по умолчанию уровень изолированности read uncommitted (чтение незафиксированных данных). При этом уровне изолированности по данному ресурсу захватывается разделяемая блокировка только до завершения чтения, и затем эта разделяемая блокировка освобождается. И если какая-либо транзакция читает одни и те же данные дважды, то результаты чтения могут не совпасть, поскольку другая транзакция могла захватить блокировку между первым и вторым чтениями и модифицировать эти данные.
Чтобы избежать проблемы повторяемости чтения, вы можете задать уровень изолированности serializable (упорядочиваемость), но это вынудит SQL Server захватить все разделяемые блокировки, необходимые для операторов SELECT во всех транзакциях, пока не будет завершена каждая транзакция. Иными словами, для целостности транзакций разделяемые блокировки будут захвачены по таблице, указанной в операторе SELECT любой транзакции. Если вы не хотите поддерживать упорядочиваемость для всех ваших транзакций, то можете добавить какую-либо подсказку блокировки для определенного запроса. Подсказка блокировки HOLDLOCK в операторе SELECT указывает SQL Server захват всех разделяемых блокировок по таблице, заданной в операторе транзакции SELECT, вплоть до конца этой транзакции – независимо от уровня изолированности. Тем самым при повторном чтении будет наблюдаться согласованность данных (они не будут изменены другой транзакцией). Использование подсказ ок блокировки не влияет на уровень изолированности для других транзакций.
Оптимизатор запросов SQL Server автоматически определяет наиболее эффективный план исполнения и типы блокировок для запроса. И поскольку оптимизатор запросов автоматически выбирает подходящие тип или типы блокировок, подсказки блокировки следует использовать, если только они хорошо изучены и когда это абсолютно необходимо, иначе они могут отрицательным образом повлиять на параллельно выполняемые задачи.
В следующем списке дается описание существующих подсказок блокировки на уровне таблиц.
HOLDLOCK. Захватывает разделяемую блокировку до завершения транзакции, а не освобождает ее сразу после того, как уже не требуется соответствующая таблица, страница или строка данных. Эквивалентно использованию подсказки блокировки SERIALIZABLE.
NOLOCK. Применяется только к оператору SELECT. Не получает разделяемых блокировок и не поддерживает монопольных блокировок; читает данные, которые монопольно захвачены другой транзакцией. Эта подсказка позволяет читать нефиксированные данные (dirty read).
PAGLOCK. Используется для блокировки на уровне страницы там, где обычно используется блокировка на уровне таблицы.
READCOMMITTED. Выполняется сканирование с тем же поведением по блокировкам, как у транзакций, использующих уровень изолированности read committed (принятый по умолчанию уровень изолированности для SQL Server).
READPAST. Применяется только к оператору SELECT и только к строкам, блокированным с помощью блокировки на уровне строк. Пропускаются строки, блокированные другими транзакциями, которые обычно включаются в набор результатов; возвращает результаты без этих блокированных строк. Может использоваться только с транзакциями, выполняемыми на уровне изолированности read committed.
READUNCOMMITTED. Эквивалентно NOLOCK.
REPEATABLEREAD. Выполняется сканирование с тем же поведением по блокировкам, как у транзакций, использующих уровень изолированности repeatable read.
ROWLOCK. Используются блокировки на уровне строк вместо блокировки на уровне страниц или на уровне таблиц.
SERIALIZABLE. Выполняется сканирование с тем же поведением по блокировкам, как у транзакций, использующих уровень изолированности serializable. Эквивалентно HOLDLOCK.
TABLOCK. Используется блокировка на уровне таблиц вместо блокировки на уровне страниц или на уровне строк. SQL Server захватывает эту блокировку до завершения оператора.
TABLOCKX. Используется монопольная блокировка по таблице. Внимание! Эта подсказка препятствует доступу других транзакций к этой таблице.
UPDLOCK. Используются блокировки изменения вместо монопольных блокировок при чтении таблицы. Эта подсказка позволяет другим пользователям только читать данные и позволяет вам изменять эти данные; тем самым никакой другой пользователь не сможет модифицировать эти данные после того, как вы в последний раз прочитали их.
Вы можете объединять совместимые подсказки блокировки, такие как TABLOCK и REPEATABLEREAD, но вы не можете объединять конфликтующие подсказки, такие как REPEATABLEREAD и SERIALIZABLE. Чтобы задать подсказку блокировки на уровне таблиц, заключите эту подсказку в круглые скобки после имени таблицы в операторе T-SQL. Следующая последовательность является примером использования подсказок TABLOCKX в операторе SELECT:
USE pubs
SELECT COUNT(ord_num)
FROM sales (TABLOCKX)
WHERE ord_date > "Sep 13 1994"
GO
Подсказка TABLOCK сообщает SQL Server, что нужно захватить монопольную блокировку на уровне таблиц по таблице продаж (sales), пока не будет выполнен данный оператор. Эта подсказка обеспечивает, что никакая другая транзакция не сможет модифицировать данные в таблице sales, пока данный запрос подсчитывает заказы из этой таблицы. Будьте осторожны, используя этот вид подсказки, поскольку блокирование доступа других транзакций к этой таблице может приводить к ожиданию других транзакций, снижению времени отклика и цепному блокированию. И снова напомним: используйте подсказки блокировки на уровне таблиц только в случае абсолютной необходимости.
6Лекция № 11. Оптимизация запросов
Продолжительность: 2 часа (90 мин.)
6.1Ключевые вопросы
Принципы работы оптимизатора, фазы оптимизации.
Логическая оптимизация запросов.
Оптимизация плана исполнения запроса
Подсказки оптимизатору запросов.
Оптимизация с использованием SQL Server 2000 Index Tuning Wizard и SQL Server 2005 Database Tuning Advisor
6.2Текст лекции
6.2.1Принципы работы оптимизатора — до 10 мин.
Прежде, чем перейти к рассмотрению конкретных проблем и решений в области оптимизации запросов, рассмотрим типичный для современных реляционных СУБД путь обработки запроса, поступившего в СУБД на языке запросов SQL. Обычно обработка запроса, выраженного на некотором языке запросов и поступившего в систему, состоит из следующих этапов или фаз:
лексический и синтаксический анализ,
синтаксическая оптимизация,
выбор оптимального плана,
произведение оптимального плана,
выполнения плана.
На первой фазе запрос, выраженный на языке запросов, подвергается лексическому и синтаксическому анализу. При этом вырабатывается его внутреннее представление, отражающее структуру запроса и содержащее информацию, которая характеризует объекты базы данных, упомянутые в запросе (отношения, поля и константы). Информация о хранимых в базе данных объектах выбирается из каталогов базы данных. Внутреннее представление запроса используется и преобразуется на следующих стадиях обработки запроса. Внутреннее представление должно выбираться так, чтобы оно было достаточно удобным для последующих оптимизационных преобразований.
На второй фазе запрос в своем внутреннем представлении подвергается логической оптимизации. При этом могут применяться различные преобразования, "улучшающие" начальное представление запроса. Среди этих преобразований могут быть эквивалентные преобразования, после проведения которых получается внутренне представление, семантически эквивалентное начальному (например, приведение запроса к некоторой канонической форме), Преобразования могут быть и семантическими, когда получаемое представление не является семантически эквивалентным начальному, но гарантируется, что результат выполнения преобразованного запроса совпадает с результатом запроса в начальной форме при соблюдении ограничений целостности, существующих в базе данных. В любом случае после выполнения второй фазы обработки запроса его внутреннее представление остается непроцедурным, хотя и является в некотором смысле более эффективным, чем начальное.
Третий этап обработки запроса состоит в выборе на основе информации, которой располагает оптимизатор, набора альтернативных процедурных планов выполнения данного запроса в соответствии с его внутреннем представлением, полученным на второй фазе. Кроме того, для каждого плана оценивается предполагаемая стоимость выполнения запроса по этому плану. При оценках используется статистическая информация о состоянии базы данных, доступная оптимизатору. Из полученных альтернативных планов выбирается наиболее дешевый, и именно его внутреннее представление теперь соответствует обрабатываемому запросу.
На четвертом этапе по внутреннему представлению наиболее оптимального плана выполнения запроса формируется выполняемое представление плана. Выполняемое представление плана может быть программой в машинных кодах, если, как в случае System R, система ориентирована на компиляцию запросов в машинные коды, или быть машинно—независимым, но более удобным для интерпретации, если, как в случае INGRES, система ориентирована на интерпретацию запросов.
Наконец, на последнем, пятом этапе обработки запроса происходит его реальное выполнение в соответствии с выполняемым планом запроса. Это либо выполнение соответствующей подпрограммы, либо вызов интерпретатора с передачей ему для интерпретации выполняемого плана.
Заметим, что для нашего рассмотрения несущественно разделение процесса обработки запроса на подготовительную (включающую фазы 1—4) и исполнительную (фазу 5) части. В нашу схему укладывается и реальное отделение по времени первых четырех фаз от пятой (подход с предварительной компиляцией запроса до реального выполнения), и последовательное выполнение всех пяти фаз при каждом выполнении запроса. Для строгости заметим, что некоторые методы оптимизации (и даже подходы к оптимизации) довольно сильно зависят от общей организации обработки запроса. При отрыве во времени процесса компиляции от реального выполнения запроса оптимизатор располагает меньшей и менее достоверной информацией, чем в том случае, когда этап компиляции тесно привязан к этапу выполнения (выполняется в рамках транзакции пользователя).
