What is implicit conversion?
Implicit conversion occurs when SQL Server automatically converts one data type to another so that two different data types can be compared or used in an expression.
DECLARE @Number INT = 100;
SELECT @Number + '50';
SQL Server automatically converts '50' from VARCHAR to INT because INT has higher data-type precedence.
Result:
150
How does it affect index usage?
If SQL Server converts the indexed column, it may be unable to perform an efficient Index Seek. It may instead perform an Index Scan, checking many or all index entries.
CREATE TABLE Employees
(
EmployeeCode VARCHAR(20)
);
CREATE INDEX IX_Employees_EmployeeCode
ON Employees(EmployeeCode);
Problem query
DECLARE @Code NVARCHAR(20) = N'E100';
SELECT *
FROM Employees
WHERE EmployeeCode = @Code;
The column is VARCHAR, but the parameter is NVARCHAR.
Because NVARCHAR has higher precedence, SQL Server may effectively apply a conversion to the indexed column:
WHERE CONVERT(NVARCHAR(20), EmployeeCode) = @Code
This can make the predicate non-SARGable and lead to an Index Scan.
Correct query
Use the same data type as the column:
DECLARE @Code VARCHAR(20) = 'E100';
SELECT *
FROM Employees
WHERE EmployeeCode = @Code;
Now SQL Server is more likely to use an Index Seek.
Why is an Index Scan slower?
-
Index Seek: Goes directly to the matching rows.
-
Index Scan: Reads many or all index entries to find matches.
On a small table, the difference may be minor. On a large table, it can cause:
-
More logical reads
-
Higher CPU usage
-
Longer query execution
-
Poor scalability
Another common example
Suppose CustomerId is a text column:
CustomerId VARCHAR(20)
Problem:
SELECT *
FROM Customers
WHERE CustomerId = 1001;
SQL Server may try to convert every CustomerId value to INT:
CONVERT(INT, CustomerId) = 1001
This can prevent an index seek and may fail if the column contains a value such as 'C1001'.
Correct:
SELECT *
FROM Customers
WHERE CustomerId = '1001';
Explicit conversion
An explicit conversion is written by the developer:
WHERE CONVERT(INT, CustomerId) = 1001
It is not automatically better. Applying CAST or CONVERT to an indexed column can still prevent efficient index usage.
If conversion is unavoidable, convert the parameter or constant—not the indexed column:
WHERE CustomerId = CONVERT(VARCHAR(20), @CustomerId)
The best solution is to use matching data types throughout the database and application.
How to identify the problem
Check the actual execution plan for:
-
CONVERT_IMPLICIT -
Index Scan instead of Index Seek
-
A warning symbol on an operator
-
“PlanAffectingConvert” warnings
You can also check logical reads:
SET STATISTICS IO ON;
Important note
Implicit conversion does not always prevent an index seek. It depends on:
-
Which side SQL Server converts
-
Data-type precedence
-
Collation
-
Index structure
-
Data distribution
-
Query cost
The main risk occurs when conversion is applied to the indexed column.
Key interview points
-
Implicit conversion is an automatic conversion performed by SQL Server.
-
SQL Server converts the lower-precedence type to the higher-precedence type.
-
Conversion on an indexed column can make the predicate non-SARGable.
-
It may change an Index Seek into an Index Scan.
-
Primary-key and foreign-key columns should use matching data types and lengths.
-
Application parameters should match the database column’s type and length.
-
Avoid applying
CAST,CONVERTor functions directly to indexed columns. -
Look for
CONVERT_IMPLICITwarnings in the execution plan.