Диагностика низкой производительности запросов. Оценка мощности

Оптимизатор запросов SQL Server основан на оценке стоимости. То есть оптимизатор выбирает планы запросов с наименьшей оценочной стоимостью их выполнения. Оптимизатор запросов определяет стоимость выполнения плана запроса исходя из двух основных факторов:

  • общего числа строк, обрабатываемых на каждом из уровней плана запроса, известного как количество элементов, или мощность плана;

  • модели стоимости алгоритма, которая определяется исходя из операторов, выполняемых в запросе.

Первый фактор, количество элементов, передается в качестве входного параметра второму фактору, модели стоимости. Обработанное таким образом количество элементов точнее определяет стоимость, что, в свою очередь, позволяет выбрать самый быстрый план выполнения запроса.

SQL Server оценивает мощность главным образом на основе гистограмм, которые создаются автоматически или вручную после создания индексов или статистик. Иногда для определения количества элементов SQL Server также использует сведения об ограничениях и логической реструктуризации запросов.

Ниже перечислены случаи, когда SQL Server не в состоянии точно вычислить мощность. Это приводит к неточному определению стоимости, что, в свою очередь, может привести к созданию неоптимальных планов запросов. Если избегать применения таких конструкций, можно повысить производительность выполнения запросов. Иногда в таких случаях доступны альтернативные формулировки запросов и другие средства, помогающие решить эту проблему.

  • Запросы с предикатами, которые содержат операторы сравнения столбцов одной и той же таблицы.

  • Запросы с предикатами, использующими операторы, и выполнение одного из следующих условий:

    • отсутствует статистика для столбца, указанного с любой стороны от оператора;

    • распределение значений в статистике неоднородно, а запрос выполняет поиск весьма ограниченного набора значений. Эта ситуация особенно вероятна, если оператор не является оператором равенства (=);

    • предикат использует оператор неравенства (!=) или логический оператор NOT.

  • Запросы с любыми встроенными функциями SQL Server или пользовательскими скалярными функциями, которым в качестве аргументов передаются выражения, отличные от констант.

  • Запросы, в которые включены столбцы, соединяемые по арифметическим операторам или объединением строк.

  • Запросы, которые сравнивают переменные, значения которых в момент компиляции и оптимизации запроса неизвестны.

Для повышения производительности перечисленных типов запросов можно попробовать предпринять следующие меры:

  • Постройте индексы или статистику для столбцов, участвующих в запросе. Дополнительные сведения см. в разделах Проектирование индексов и Использование статистики для повышения производительности запросов.

  • Попробуйте использовать вычисляемые столбцы или перепишите запрос, если он содержит операторы, которые сравнивают или производят арифметические операции над двумя и более столбцами. Например, в следующем запросе сравниваются значения в двух столбцах:

    SELECT * FROM MyTable
    WHERE MyTable.Col1 > MyTable.Col2
    

    Можно повысить производительность, добавив вычисляемый столбец Col3 к таблице MyTable, который подсчитывает разницу между Col1 и Col2 (Col1 минус Col2). Затем переписать запрос:

    SELECT * FROM MyTable
    WHERE Col3 > 0
    

    Возможно, производительность еще больше повысится, если построить индекс для столбца MyTable.Col3.