为什么没有全扫描(在SQL 2008 R2和2012上)?
测试数据:
DROP TABLE dbo.TestTable
GO
CREATE TABLE dbo.TestTable
(
TestTableID INT IDENTITY PRIMARY KEY,
VeryRandomText VarChar(50),
VeryRandomText2 VarChar(50)
)
Go
Set NoCount ON
Declare @i int
Set @i = 0
While @i < 10000
Begin
Insert Into dbo.TestTable(VeryRandomText, VeryRandomText2)
Values(Cast(Rand()*10000000 as VarChar(50)), Cast(Rand()*10000000 as VarChar(50)));
Set @i = @i + 1;
End
Go
CREATE Index IX_VeryRandomText On dbo.TestTable
(
VeryRandomText
)
Go
执行查询时:
Select * From dbo.TestTable Where VeryRandomText = N'111' -- bad
得到警告(如预期,因为将nchar数据与varchar列进行比较):
<PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT_IMPLICIT(nvarchar(50),[DemoDatabase].[dbo].[TestTable].[VeryRandomText],0)" />
但是然后我看到了执行计划,并且可以看到它没有像我期望的那样使用全扫描,而是使用索引查找。
当然,这是一种好习惯,因为在这种特殊情况下,执行速度要比全扫描时快。
但是我不明白SQL Server是如何决定制定此计划的。
另外,如果服务器排序规则是服务器级别的Windows排序规则和SQL Server排序规则数据库级别,则它将导致对同一查询的完全扫描。