Skip to content

Неявное преобразование, что это?

Пересказ статьи Monica Rathbun. What is Implicit Conversion?



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



Давайте рассмотрим очень простой, но общий сценарий неявного преобразования. В нем таблица Employee содержит столбец NationalIDNumber, который определен на типе данных NVARCHAR. В запросе мы будем использовать предложение WHERE для поиска опреденного ID.



В нижеприведенном запросе мы запрашиваем NationalIDNumber, равный целому значению 14417807. Для сравнения этих двух типов данных SQL Server должен преобразовать NVARCHAR к INT. Это означает, что каждое значение в этом столбце должно пройти процесс преобразования, что вызывает сканирование таблицы (table scan).

USE AdventureWorks2016CTP3 
GO
SET STATISTICS IO ON
GO
SELECT BusinessEntityID, NationalIDNumber, LoginID, HireDate,JobTitle
FROM HumanResources.Employee
WHERE NationalIDNumber = 14417807

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





(1 row affected)
Table ‘Employee’. Scan count 1, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Вопрос - как исправить это. Это действительно просто, но потребует изменения кода. Давайте вернемся к нашему запросу.

SELECT BusinessEntityID, NationalIDNumber, LoginID, HireDate,JobTitle
FROM HumanResources.Employee
WHERE NationalIDNumber = 14417807

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

SELECT BusinessEntityID, NationalIDNumber, LoginID, HireDate,JobTitle
FROM HumanResources.Employee
WHERE NationalIDNumber = '14417807'

Просто посмотрим на результаты. Напомним, что выше мы имели число сканирований 1, логических чтений 9, физических чтений 0. Теперь при выполнении получим:

(1 row affected)
Table ‘Employee’. Scan count 0, logical reads 4, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

На графическом плане также видно, что предупреждение ушло, и мы имеем SEEK вместо SCAN, что значительно эффективней.



Имеется много способов, с помощью которых вы можете решить проблемы, связанные с неявными или явными преобразованиями и дополнительной нагрузкой, которую они создают. В большинстве случаев очень легко поправить ситуацию путем незначительных изменений в коде. Чтобы помочь вам найти их в вашей среде, Jonathan Kehayia написал запрос для нахождения столбцов с неявным преобразованием в кэше планов.
Категории: T-SQL

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

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

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

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.