Заметки Дмитрия Пилюгина о Microsoft SQL Server 

Twitter RSS
Home SQL Server (все заметки) USE HINT и новые указания запросов в SQL Server 2016 SP1
formats

USE HINT и новые указания запросов в SQL Server 2016 SP1

«Query Hints» в документации переводится как «указания запросов», кто-то называет их «подсказками», но чаще говорят просто «хинты». Я буду использовать в заметке именно последнее выражение, т.к. оно более распространено в повседневной жизни и сразу дает понять, о чем идет речь. Эта публикация — введение, она открывает цикл заметок по новым хинтам, которые появились в SQL Server 2016 SP1.

Существуют разные мнения по поводу использования хинтов в запросах от «никогда их не используйте» до «если что-то работает плохо, все решается хинтом».

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

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

Хинтов запроса существует довольно много, но мы остановимся на тех, что появились в SQL Server 2016 SP1, и которые можно использовать при помощи ключевого слова USE HINT. Они могут быть получены при помощи нового представления sys.dm_exec_valid_use_hints. Ниже приведена таблица доступных хинтов с кратким описанием.

Hint Описание TF
DISABLE_OPTIMIZED_NESTED_LOOP Отключает оптимизацию batch sort в соединении вложенными циклами  2340*
FORCE_LEGACY_CARDINALITY_ESTIMATION Включает «старый» механизм оценки (версия 70, применялся до SQL Server 2014) 9481
ENABLE_QUERY_OPTIMIZER_HOTFIXES Включить исправления оптимизатора 4199
DISABLE_PARAMETER_SNIFFING Отключить прослушивание параметров 4136
ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES При оценке комплексных предикатов использовать предположение минимальной селективности 4137 (<2014)
9471 (>=2014)
ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS Включает зависимость селективности соединения от предикатов по таблицам 9476
ENABLE_HIST_AMENDMENT_FOR_ASC_KEYS Включить автоматическое дополнение гистограммы статистики при оценке предиката по колонке, вне зависимости возрастания/убывания ее значений 4139
DISABLE_OPTIMIZER_ROWGOAL Отключить механизм учета целевого числа строк при построении плана запроса 4138
FORCE_DEFAULT_CARDINALITY_ESTIMATION Установить версию модели оценки, соответствующую уровню совместимости БД

Чтобы применить хинт к запросу, необходимо в предложении OPTION указать ключевое слово USE HINT и в скобках перечислить один или несколько хинтов, например:

select 
	name
from 
	sys.all_columns
option( 
	use hint(
		'FORCE_LEGACY_CARDINALITY_ESTIMATION', 
		'ENABLE_QUERY_OPTIMIZER_HOTFIXES'
		)
);

Многое из того что позволяют делать хинты USE HINT было ранее доступно при помощи флагов трассировки, они перечислены в последнем столбце таблицы. Минус подходов с флагами это – слабая самодокументированность (нужно помнить, какой номер флага за что отвечает), и необходимость привилегий SA, и, хотя для последнего есть обходной путь, это не очень удобно.

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

В следующей заметке, мы поговорим про хинт DISABLE_OPTIMIZED_NESTED_LOOP.

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Анти-спам: введите результат (цифрами) *