我在 SQL Server 2008 R2 上针对下表运行简单查询:
Id (int, not null)
启用(位,不为空)
两列都有单独的索引。
所以当我运行以下查询时:
SELECT Id FROM Entities WHERE Enabled = 1
执行计划显示 INDEX_SCAN 已完成(这是由 Enabled 列上的 CONVERT_IMPLICIT 引起的)
当我运行另一个查询时:
SELECT Id FROM Entities WHERE Enabled = '1'
或
SELECT Id FROM Entities WHERE Enabled = 'true'
或
SELECT Id FROM Entities WHERE Enabled = CAST(1 AS BIT)
执行计划显示 INDEX_SEEK 已完成。
由于 CONVERT_IMPLICIT 会影响更复杂查询的性能,我想知道是什么导致 SQL Server 如此运行?
更新:
如果我跑
SELECT Id FROM Entities WHERE Enabled = 0
然后
SELECT Id FROM Entities WHERE Enabled = 1
执行计划显示 INDEX_SEEK。 在这种情况下,我认为 SQL Server 收集了一些优化统计信息并最终了解到没有理由使用 CONVERT_IMPLICIT。但遗憾的是,我不能保证我的初始查询会以相反的值执行。
如果我能得到任何澄清,我会很高兴。
最佳答案
您是否在 2000 兼容模式下使用数据库?当我阅读 here ,如果你使用这种兼容模式,你会遇到这个“问题”,但在 2005 或 2008 兼容模式下你不会。
因此,如果您需要使用 2000 兼容模式,则必须使用“= '1'”比较来避免 CONVERT_IMPLICIT,因为 bit 和 int(或 tiny int)之间的类型优先级使得该位必须“升级”为 int。
关于SQL Server 2008 R2 将 CONVERT_IMPLICIT tinyint 转换为位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10028158/