I’m running the simple query on SQL Server 2008 R2 for the following table:
Id (int, not null)
Enabled (bit, not null)
Both columns has separate indexes.
So when I run the following query:
SELECT Id FROM Entities WHERE Enabled = 1
Execution plan show that an INDEX_SCAN is done (it is caused by CONVERT_IMPLICIT on Enabled column)
And when I run another query:
SELECT Id FROM Entities WHERE Enabled = '1'
or
SELECT Id FROM Entities WHERE Enabled = 'true'
or
SELECT Id FROM Entities WHERE Enabled = CAST(1 AS BIT)
Execution plan shows that INDEX_SEEK is done.
As CONVERT_IMPLICIT can affect performance in more complex queries, I want to know what is causing SQL Server to behave so?
UPD:
If I run
SELECT Id FROM Entities WHERE Enabled = 0
and then
SELECT Id FROM Entities WHERE Enabled = 1
Execution plan shows INDEX_SEEK.
In this case I think SQL Server gathered some optimization statistics and finally learned that there is no reason for a CONVERT_IMPLICIT. But pitily, I cannot guarantee that my initial query will be ever executed with the opposite value.
I will be happy with any clarification I can get.
Are you using a database in 2000 compatibility mode? As I read here , if you use this compatibility mode you’ll take this “problem”, but whit 2005 or 2008 compatibility mode you wont.
So, if you need to use 2000 compatibility mode, you’ll have to use the “= ‘1’” comparation to avoid CONVERT_IMPLICIT, becuasue the type precedence between bit and int (or tiny int) makes the bit had to “upgrade” to int.