更改这个查询来与一个字符串常数比较,这个问题将得到解决:
SELECT EmployeeID, NationalIDNumber, LoginID
FROM HumanResources.Employee
WHERE NationalIDNumber = '112457891'
go
FROM HumanResources.Employee
WHERE NationalIDNumber = '112457891'
go
这些信息现在显示为零扫描,这正是我们想要的。在这个案例中,逻辑读的不同点是只有2,这是因为Employee很小。如果在数百万行的表上进行这个过程,那么逻辑读的不同点将变成几千。
EmployeeID NationalIDNumber LoginID
----------- ---------------- ----------------------
4 112457891 adventure-works\rob0
(1 row(s) affected)
Table 'Employee'. Scan count 0, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
查询计划显示查找和主键查找正是我们希望看到的。
图三
一个字符串用于存储一个数字型主键的问题是很常见的。SQL Server将很忠实地执行隐式转换并返回正确的结果,但是要以较差的性能为代价,通过一个扫描而不是查找来进行并且要正确使用该索引。
下一步
要一直警惕隐式转换,尤其是有存储数字型键的字符串的时候。
我甚至在varchar字段与nvarchar字段进行比较的时候看到这个问题。
更正这个问题是很简单的,你只需要确保在相似的数据类型上执行比较。