Руководство по оптимизации и проверке после миграции

Область применения:SQL Server

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

Обычные сценарии производительности

Ниже приведены некоторые распространенные сценарии производительности, возникающие после миграции на платформу SQL Server и способы их устранения. К ним относятся сценарии, характерные для миграции из SQL Server в SQL Server (со старых версий на новые), а также для миграции со сторонних платформ (например, Oracle, DB2, MySQL и Sybase) в SQL Server.

Регрессии запросов вследствие изменения версии оценщика кратности (CE)

Область применения:мигарция с SQL Server на SQL Server.

При переходе с более старой версии SQL Server на SQL Server 2014 (12.x) или более поздних версий и обновлении уровня совместимости базы данных до последней доступной рабочей нагрузки может быть подвержена риску регрессии производительности.

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

Дополнительные сведения об изменениях оптимизатора запросов, внесенных в SQL Server 2014 (12.x), см. в документе Оптимизация планов запросов с помощью оценщика кратности SQL Server 2014

Дополнительные сведения об оценке кратности (CE) см. в разделе Оценка кратности (SQL Server).

Действия по устранению

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

Схема, на которой показан рекомендуемый рабочий процесс обновления.

Дополнительные сведения об этой статье см. в статье "Сохранение стабильности производительности во время обновления до более нового SQL Server".

Чувствительность к анализу параметров

Применяется к: миграции с внешней платформы (например, Oracle, DB2, MySQL и Sybase) на SQL Server.

Примечание.

При миграции с SQL Server на SQL Server, если эта проблема присутствовала в исходной версии SQL Server, перенос на более новую версию SQL Server без изменений не устраняет эту ситуацию.

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

Потенциальная проблема возникает, когда первая компиляция не использует наиболее распространенные наборы параметров для обычной рабочей нагрузки. С другими параметрами план выполнения будет неэффективным. Дополнительные сведения об этой статье см. в разделе "Конфиденциальность параметров".

Действия по устранению

  1. Воспользуйтесь подсказкой RECOMPILE. Для каждого значения параметра план вычисляется заново.

  2. Перепишите хранимую процедуру, задействовав параметр (OPTIMIZE FOR(<input parameter> = <value>)). Определите, какое значение соответствует большей части рабочей нагрузки — это позволит создать и использовать единый план, который будет эффективным для параметризованного значения.

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

  4. Перепишите хранимую процедуру, задействовав параметр (OPTIMIZE FOR UNKNOWN). Результат будет точно таким же, как при использовании локальной переменной.

  5. Перепишите запрос, задействовав подсказку DISABLE_PARAMETER_SNIFFING. Результат будет таким же, как при использовании локальной переменной — в отсутствие OPTION(RECOMPILE), WITH RECOMPILE или OPTIMIZE FOR <value> сканирование параметра будет полностью отключено.

Совет

Используйте функцию анализа планов Management Studio, чтобы быстро определить, является ли это проблемой. Дополнительные сведения см. в статье Новое в SSMS: устранение неполадок, связанных с производительностью запросов, стало проще.

Отсутствующие индексы

Применяется к: миграции с внешних платформ (например, Oracle, DB2, MySQL и Sybase) и миграции с SQL Server на SQL Server.

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

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

Действия по устранению

  1. Используйте графический план выполнения для поиска любых ссылок на отсутствующие индексы.

  2. Индексирование предложений, созданных помощником по настройке ядра СУБД.

  3. Используйте sys.dm_db_missing_index_details.

  4. Используйте существующие скрипты, которые задействуют имеющиеся динамические административные представления (DMV), чтобы получить сведения об отсутствующих, дублирующихся, избыточных, редко используемых и совершенно неиспользуемых индексах, а также определить, есть ли в существующих процедурах и функциях вашей базы данных ссылки на индексы, заданные с помощью hint’ов или захардкоженные.

Совет

Примерами таких предварительных сценариев являются создание индекса и сведения о индексе.

Неспособность использовать предикаты для фильтрации данных

Применяется к: миграции с внешних платформ (например, Oracle, DB2, MySQL и Sybase) и миграции с SQL Server на SQL Server.

Примечание.

При миграции с SQL Server на SQL Server, если эта проблема присутствовала в исходной версии SQL Server, перенос на более новую версию SQL Server без изменений не устраняет эту ситуацию.

Оптимизатор запросов SQL Server работает только с теми данными, которые известны на момент компиляции. Если рабочая нагрузка выполняется с предикатами, которые могут быть известны только во время выполнения, вероятность неадекватного выбора плана возрастает. Для более качественного плана предикаты должны быть SARGable.

Примечание.

Термин SARGable в реляционных базах данных обозначает предикат, Search ARGumentable, который может использовать индекс для ускорения выполнения запроса. Дополнительные сведения см. в руководстве по архитектуре и проектированию индексов SQL Sql Server и Azure.

Некоторые примеры предикатов, отличных от SARGable :

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

  • Сложные неопределенные выражения, такие как WHERE UnitPrice + 1 < 3.975, но не WHERE UnitPrice < 320 * 200 * 32.

  • Выражения с функциями, такие как WHERE ABS(ProductID) = 771 или WHERE UPPER(LastName) = 'Smith'.

  • Строки, которые начинаются с подстановочных знаков, такие как WHERE LastName LIKE '%Smith', но не WHERE LastName LIKE 'Smith%'.

Действия по устранению

  1. Всегда объявлять переменные и параметры в качестве целевых типов данных.

    Это может включать сравнение любого определяемого пользователем конструктора кода, хранящегося в базе данных (например, хранимых процедур, определяемых пользователем функций или представлений) с системными таблицами, которые содержат сведения о типах данных, используемых в базовых таблицах (например, sys.columns).

  2. Если перебрать весь код до указанной выше точки нельзя, то с той же целью можно изменить тип данных в таблице в соответствии с объявлением переменной или параметра.

  3. Рассмотрите целесообразность применения следующих конструкций:

    • функции, используемые в качестве предикатов;
    • поиск с подстановочными знаками;
    • Сложные выражения на основе столбцовых данных — оцените, не лучше ли вместо этого создать сохраняемые вычисляемые столбцы, которые можно индексировать;

Примечание.

Все эти действия можно выполнить программным способом.

Использование табличнозначных функций (многооператорные и встроенные)

Применяется к: миграции с внешних платформ (например, Oracle, DB2, MySQL и Sybase) и миграции с SQL Server на SQL Server.

Примечание.

При миграции с SQL Server на SQL Server, если эта проблема присутствовала в исходной версии SQL Server, перенос на более новую версию SQL Server без изменений не устраняет эту ситуацию.

Табличнозначные функции возвращают табличный тип данных и могут служить альтернативой представлениям. В то время как представления ограничены одной инструкцией SELECT, пользовательские функции могут содержать дополнительные инструкции, обеспечивающие более обширную логику, чем та, которая возможна в представлениях.

Поскольку результирующая таблица многокомандной табличной функции (MSTVF) не создается на этапе компиляции, оптимизатор запросов SQL Server использует эвристики, а не фактическую статистику, для оценки количества строк.

Даже если индексы добавляются в базовые таблицы, это не поможет.

Для функций MSTVF SQL Server в качестве количества строк, которое должна возвращать такая функция, использует фиксированное значение 1 (начиная с SQL Server 2014 (12.x) фиксированное значение составляет 100 строк).

Действия по устранению

  1. Если MSTVF состоит только из одной инструкции, преобразуйте её во встроенную табличнозначную функцию.

    CREATE FUNCTION dbo.tfnGetRecentAddress (@ID INT)
    RETURNS
        @tblAddress TABLE ([Address] VARCHAR (60) NOT NULL)
    AS
    BEGIN
        INSERT INTO @tblAddress ([Address])
        SELECT TOP 1 [AddressLine1]
        FROM [Person].[Address]
        WHERE AddressID = @ID
        ORDER BY [ModifiedDate] DESC;
        RETURN;
    END
    

    Ниже приведён пример встроенного формата.

    CREATE FUNCTION dbo.tfnGetRecentAddress_inline
    (@ID INT)
    RETURNS TABLE
    AS
    RETURN
        (SELECT TOP 1 [AddressLine1] AS [Address]
         FROM [Person].[Address]
         WHERE AddressID = @ID
         ORDER BY [ModifiedDate] DESC)
    
  2. Для более сложных вариантов можно использовать промежуточные результаты, которые хранятся в таблицах, оптимизированных для памяти, или во временных таблицах.