Обработка неявного преобразования
Пересказ статьи 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
Во всяком случае мы можем щелкнуть план запроса и увидеть, где у нас проблемы:
Создаете ли вы новые таблицы, или разрабатываете запросы, адресующиеся к существующим таблицам, убедитесь, что вы тщательно проверили типы данных. Это будет иметь значение.
Обратные ссылки
Автор не разрешил комментировать эту запись
Комментарии
Показывать комментарии Как список | Древовидной структурой