Обработка инструкций SQL
Обработка одиночной инструкции SQL — наиболее распространенный способ, с помощью которого SQL Server выполняет инструкции SQL. Шаги, используемые для обработки одиночной инструкции SELECT, которая обращается только к таблицам локальной базы (а не к представлениям и не к удаленным таблицам), иллюстрируют основной процесс.
Оптимизация инструкций SELECT
Инструкция SELECT является непроцедурной; она не определяет точные шаги, которые сервер базы данных должен предпринять, для получения запрошенных данных. Это означает, что сервер базы данных должен проанализировать инструкцию для определения самого эффективного способа извлечения запрошенных данных. Это упоминается как оптимизация инструкции SELECT. Выполняющий это компонент называют оптимизатором запросов. Входные данные оптимизатора состоят из самого запроса, схемы базы данных (определений таблиц и индексов) и статистики базы данных. Выходные данные оптимизатора — план выполнения запроса, иногда называемый планом запроса или просто планом. Содержимое плана запроса описывается более подробно далее в этом разделе.
Входные и выходные данные оптимизатора запросов при оптимизации одиночной инструкции SELECT проиллюстрированы в следующей диаграмме:
Инструкция SELECT определяет только следующее.
Формат результирующего набора. Он указан, главным образом, в списке выбора. Однако другие предложения, например ORDER BY и GROUP BY, также затрагивают конечную форму результирующего набора.
Таблицы, которые содержат исходные данные. Указываются в предложении FROM.
Как таблицы логически связаны с целями инструкции SELECT. Это определяется в спецификациях соединения, которые могут появляться в предложении WHERE или в предложении ON, следующем за предложением FROM.
Условия, которым строки в исходных таблицах должны соответствовать для выбора их инструкцией SELECT. Указываются в предложениях WHERE и HAVING.
План выполнения запроса представляет собой определение следующего.
Последовательности, в которой происходит обращение к исходным таблицам.
Как правило, существует много последовательностей, в которых сервер базы данных может обращаться к базовым таблицам для построения результирующего набора. Например, если инструкция SELECT ссылается на три таблицы, сервер базы данных сначала может обратиться к TableA, использовать данные из TableA для извлечения соответствующих строк из TableB и затем использовать данные из TableB для извлечения данных из TableC. Другие последовательности, в которых сервер базы данных может обращаться к таблицам:
TableC, TableB, TableA или
TableB, TableA, TableC или
TableB, TableC, TableA или
TableC, TableA, TableB
Методы, используемые для извлечения данных из каждой таблицы.
Есть различные методы для обращения к данным в каждой таблице. Если необходимы только несколько строк с определенными ключевыми значениями, то сервер базы данных может использовать индекс. Если необходимы все строки в таблице, то сервер базы данных может пропустить индексы и выполнить просмотр таблицы. Если необходимы все строки в таблице, но есть индекс, ключевые столбцы которого находятся в ORDER BY, то выполнение просмотра индекса вместо просмотра таблицы позволит избежать отдельный сортировки результирующего набора. Если таблица является очень маленькой, то просмотры таблицы могут быть самым эффективным методом для практически всех обращений к таблице.
Процесс выбора одного плана выполнения из множества потенциально возможных планов называется оптимизацией. Оптимизатор запросов является одним из самых важных компонентов системы базы данных SQL. Хотя для анализа запроса и выбора плана оптимизатору запросов требуются некоторые накладные расходы, эти накладные расходы обычно многократно окупаются, когда оптимизатор запроса выбирает эффективный план выполнения. Например, двум строительным компаниям могут быть предоставлены идентичные проекты дома. Если одна компания потратит сначала несколько дней на планирование того, как она будет строить дом, а другая компания начнет строить без планирования, то компания, которая потратит время на планирование проекта, вероятно, закончит первой.
Оптимизатор запросов SQL Server основан на оценке стоимости. Каждому возможному плану выполнения соответствует некоторая стоимость, определенная в терминах объема использованных вычислительных ресурсов. Оптимизатор запросов должен проанализировать возможные планы и выбрать один файл с самой низкой предполагаемой стоимостью. Некоторые сложные инструкции SELECT имеют тысячи возможных планов выполнения. В этих случаях оптимизатор запросов не анализирует все возможные комбинации. Вместо этого он использует сложные алгоритмы поиска плана выполнения, имеющего стоимость, близкую к минимальной возможной стоимости.
Оптимизатор запросов SQL Server не выбирает план выполнения, основываясь только на самой низкой стоимости ресурсов; он выбирает такой план, который возвращает результаты пользователю при разумной стоимости ресурсов, но делает это быстрее других. Например, параллельная обработка запроса обычно использует больше ресурсов, чем его последовательная обработка, но завершает выполнение запроса быстрее. Оптимизатор SQL Server будет использовать параллельный план выполнения для возврата результатов, если это не окажет неблагоприятного влияния на загрузку сервера.
Оптимизатор запросов полагается на статистику распределения, когда он оценивает затраты ресурсов для различных методов извлечения сведений из таблицы или индекса. Статистика распределения хранится для столбцов и индексов. Она указывает селективность значений в определенном индексе или столбце. Например, в таблице, представляющей автомобили, много автомобилей имеют одного производителя, но каждый автомобиль имеет уникальный идентификационный номер транспортного средства (VIN). Индекс по VIN является более селективным, чем индекс по производителям. Если статистика индекса не является текущей, оптимизатор запросов, возможно, не сделает лучший выбор для текущего состояния таблицы. Дополнительные сведения о хранении текущей статистики индекса см. в разделе Использование статистики для повышения производительности запросов.
Оптимизатор запросов важен, потому что дает возможность серверу базы данных вносить динамическую коррекцию в изменяющиеся условия в базе данных, не требуя ввода данных от администратора базы данных или программиста. Это дает возможность программистам сосредоточиться на описании конечного результата запроса. Они могут полагаться на то, что оптимизатор запросов будет создавать эффективный план выполнения с учетом состояния базы данных каждый раз при выполнении инструкции.
Обработка инструкции SELECT
Основные шаги, используемые SQL Server для обработки одиночной инструкции SELECT, включают следующее:
Синтаксический анализатор просматривает инструкцию SELECT и разбивает ее на логические единицы, такие как ключевые слова, выражения, операторы и идентификаторы.
Строится дерево запроса, иногда называемое деревом последовательности, с описанием логических шагов, необходимых для преобразования исходных данных в формат, требуемый результирующему набору.
Оптимизатор запросов анализирует различные способы, с помощью которых можно обратиться к исходным таблицам. Затем он выбирает ряд шагов, которые возвращают результаты быстрее всего и используют меньше ресурсов. Дерево запроса обновляется для записи этого точного ряда шагов. Конечную, оптимизированную версию дерева запроса называют планом выполнения.
Реляционный механизм начинает реализовывать план выполнения. В ходе обработки шагов, требующих данных из базовых таблиц, реляционный механизм запрашивает у подсистемы хранилища передачу данных из набора строк, указанных реляционным механизмом.
Реляционный механизм преобразует данные, возвращенные подсистемой хранилища, в заданный для результирующего набора формат и возвращает результирующий набор клиенту.
Обработка других инструкций
Основные шаги, описанные для обработки инструкции SELECT, применимы к другим инструкциям SQL, таким как INSERT, UPDATE и DELETE. Инструкции UPDATE и DELETE имеют адресатом набор строк, которые будут изменены или удалены. Процесс идентификации этих строк является тем же процессом, что и процесс, используемый для идентификации исходных строк, определяющих результирующий набор инструкции SELECT. Инструкции UPDATE и INSERT могут обе содержать встроенные инструкции SELECT, предоставляющие значения данных, которые будут обновлены или вставлены.
Даже инструкции языка определения данных (DDL), такие как CREATE PROCEDURE или ALTER TABLE, в конечном счете приводятся к ряду реляционных операций на таблицах системного каталога, а иногда (для ALTER TABLE ADD COLUMN) на таблицах данных.