SQL Server. Неявное приведение типов

SQL Server. Неявное приведение типов

Неявное приведение типов данных, которое в определенных случаях допускается в T-SQL — очень удобная штука. Для новичка. С приобретением опыта, разработчики стараются держать все под контролем и чаще скорее сами стараются определить, каким образом значение должно преобразовываться из одного типа в другой. Дело дошло до того, что возможность полного запрета на неявную конвертацию регулярно запрашивается сообществом пользователей SQL Server у разработчиков…
Чем же так плохо наличие вроде бы очень удобного, прощающего ошибки и сокращающего код функционала СУБД?

Рассмотрим пример:

Во втором запросе будет использоваться неявное приведение типов для сопоставления числовой переменной и строкового поля.

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

1. Производительность
Если посмотреть планы выполнения запросов из примера, то можно увидеть, что индекс по первичному ключу будет использован в первом запросе и не будет — во втором. (Использовался SQL Server 2008 R2 build 1600, в других версиях планы выполнения могут быть другие)
Причина в том, что в данном случае сервер принял решение приводить значение поля к типу данных int, что привело к необходимости сканирования всех значений данного поля. (Поиск по индексу возможен тогда, когда нужно найти конкретное значение, которое заранее неизвестно в случае необходимости преобразования проиндексированных значений).
В реальных базах мне встречались случаи, когда вроде бы подходящие индексы не использовались из-за приведения типов int<>smallint или varchar<>nvarchar

2. Ошибки
Если в таблицу @detail примера вставить значение ID, которое нельзя привести к типу int, то второй запрос завершится с ошибкой:

Msg 245, Level 16, State 1, Line 12
Conversion failed when converting the varchar value ‘a’ to data type int.

В данном случае не поможет даже фильтрация записей, в поле ID которых содержатся только цифры — сервер может сам определять порядок применения операторов.

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

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

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

 

Расшифровка данных, возвращаемых данным запросом — в статье Статистика, собираемая SQL Server по наиболее тяжелым запросам.

Автор: Дмитрий Костылёв

***   ***   ***   ***   ***   ***   ***   ***   ***   ***   ***   ***
Полезные Скрипты

Рубрика Проверь себя

Ссылка на наш канал YouTube

Запись опубликована в рубрике Полезно и интересно с метками . Добавьте в закладки постоянную ссылку.

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

Войти с помощью: