Skip to content

Обработка неявного преобразования

Пересказ статьи Chad Callihan. Handling Implicit Conversion


Неявное преобразование имеет место, когда SQL Server необходимо автоматически обработать несоответствие типов в данных. SQL Server делает это путем приведением типа к соответствию. Какие типы данных приводятся, и к каким? Очень рад, что вы спросили, поскольку у Microsoft есть диаграмма, отвечающая именно на этот вопрос:



Почему неявное преобразование является проблемой? Оно оказывает влияние на производительность и, как вы увидите далее, может повлиять на оценки кардинального числа (числа строк).

Пример неявного преобразования


Давайте рассмотрим пример запроса с неявным преобразованием.

Создадим общую таблицу и вставим в нее несколько записей:

USE ExampleDB;
GO
CREATE TABLE Emp (
ID INT IDENTITY(1, 1) PRIMARY KEY
,LastName VARCHAR(50) NULL
,SSN CHAR(9) NULL
);
GO
INSERT INTO Emp
VALUES ('Callihan','123456789')
,('Doe','112233445')
,('Smith','008675309');
GO

Теперь давайте выполним запрос поиска конкретного значения SSN, и включим вывод актуального плана выполнения. Когда вы создавали нашу таблицу, то определили SSN как CHAR(9). Когда мы собираемся писать поисковый запрос к таблице Emp, то можем подумать, что "SSN всегда содержит только цифры, и поэтому нет нужды в одинарных кавычках." По этой причине здесь мы, вместо поиска типа CHAR, просто используем числовые значения:

SELECT * FROM Emp
WHERE SSN = 123456789;
GO



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



Мы имеем проблему неявного преобразования. Если выполнить тот же запрос, но добавить кавычки вокруг SSN, то мы сравним CHAR с CHAR:

SELECT * FROM Emp
WHERE SSN = '123456789';
GO



Как видно, желтый восклицательный знак пропал.

Проверка на неявное преобразование


Как узнать, имеет ли место неявное преобразование на вашем SQL Server? Один просто способ - это выполнить процедуру sp_BlitzCache, которая является частью комплекта First Responder Kit от Brent Ozar. Выполняя sp_BlitzCache для нашего примера, увидим следующее:



Другой способ - это выполнить запрос такого вида:

SELECT DB_NAME(qp.dbid) AS 'Database'
,qs.creation_time
,qs.last_execution_time
,st.text
,qp.query_plan
FROM sys.dm_exec_query_stats qs
OUTER APPLY sys.dm_exec_sql_text(sql_handle) st
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qp
WHERE CAST(query_plan AS VARCHAR(MAX)) LIKE ('%CONVERT_IMPLICIT%')
GO



Во всяком случае мы можем щелкнуть план запроса и увидеть, где у нас проблемы:



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

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

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

Комментарии

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

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

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

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

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

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