Data Mismatch on WHERE Clause might Cause Serious Performance Problems
Like Applying Function on WHERE clause problem, any datatype mismatch on WHERE clause might cause serious performance problems.
Predicates on both sides of comparisons (for example on WHERE clause) always must match datatypes. It means that if the left side of predicate is integer than the right side needs to be integer. If the datatypes are different then SQL Server tries to make and implicit conversion to match the datatypes of both sides like below example.
If an implicit conversion is not possible SQL Server returns an error like below.
When an implicit conversion is possible, SQL Server automatically converts the data from one data type to another. Selection of the conversion direction depends on data loss possibility. SQL server choose the side which is to avoid data lost. For example, when a smallint is compared to an int, the smallint is implicitly converted to int before the comparison proceeds. (You can check this link to see all explicit and implicit data type conversions that are allowed for SQL Server system-supplied data types. )
The potential problem arises when the index column is selected to convert. It makes impossible to use any index on this column and causing serious performance problems
Let’s make some demos to see this problem
/*
Turgay Sahtiyan - Microsoft SQL Server Premier Field Engineer
Blog : www.turgaysahtiyan.com
Twitter : @turgaysahtiyan
*/
--Data Mismatch on Where Clause
--Create a work database
create database DBDataMismatch
GO
use DBDataMismatch
GO
--Create a work table
create table tblDataMismatch(ID int identity(1,1),Col1 varchar(10))
GO
--Populate it with 10.000 records
declare @i int=0
while @i<10000 begin
insert tblDataMismatch
select cast(@i as varchar(10))
set @i=@i+1
end
--Create a clustered index on ID column
Create Clustered Index CI_1 on tblDataMismatch(ID)
--Create a nonclustered index on col1 column
Create NonClustered Index IX_1 on tblDataMismatch(Col1)
--Work table is ready
select * from tblDataMismatch
--This query does index seek
select * from tblDataMismatch
Where Col1 = '111'
--But this one does index scan because there is a data mismatch and col1 is selected to convert
select * from tblDataMismatch
Where Col1 = 111
--This also does index scan
declare @value NVarchar(10)='111'
select * from tblDataMismatch
Where Col1 = @Value
--Drop work database
use master
go
drop database DBDataMismatch
Comments
- Anonymous
March 08, 2016
wow what a strange response to such a difficult question great work http://www.montpezat.nl/