我在查询下面运行,因为它几乎从表中返回所有记录,它应该使用索引扫描而不是查找。任何人,请解释为什么它使用搜索而不是扫描。
DROP TABLE tblPlanDiff
GO
CREATE TABLE tblPlanDiff(Sno int identity,Col_1 int,Col_2 int)
GO
DECLARE @i int=1
WHILE(@i<=200000)
BEGIN
BEGIN TRAN
INSERT INTO tblPlanDiff values(@i*2,@i*3)
COMMIT TRAN
SET @i+=1
END
CREATE UNIQUE CLUSTERED INDEX ix_Sno on tblplandiff(Sno ASC)
GO
CREATE INDEX ix_Col1_Col2 on tblplandiff(Col_1) INCLUDE(Col_2)
GO
SELECT sno,col_1,col_2 FROM tblPlanDiff
WHERE col_1>2
答案 0 :(得分:1)
由于您在Col_1
上有索引,因此可以在该索引中查找Col_1
值大于2的点。仅仅因为它正在做一个寻求并不意味着它不寻求许多行。
如果您看到扫描,则表示它从索引的开头开始并从那里扫描。从某种意义上说,Index Seek可能仍在“扫描”;它只是从索引中的精确位置开始。
无论哪种方式,你为什么希望扫描一个寻求者?
答案 1 :(得分:1)
正如我在评论中已经提到的那样:为什么你担心要寻找索引?
ix_Col1_Col2
上的Col_1
索引包含Col_2
作为附带列,并且还包含来自聚集索引的Sno
- 因此它包含您需要的所有三列满足您的查询。
所以最后,查询优化器会选择如何处理这个查询 - 它似乎更喜欢索引查找 - 我根本没有看到任何问题。
在我的SQL Server 2008 R2开发人员版上运行此查询时,我有这些perf值:
Table 'tblPlanDiff'.
Scan count 1, logical reads 797, physical reads 3, read-ahead reads 499,
SQL Server Execution Times: CPU time = 47 ms, elapsed time = 855 ms.
当我使用WITH (FORCESCAN)
查询提示运行相同的查询时,我得到:
Table 'tblPlanDiff'.
Scan count 1, logical reads 797, physical reads 3, read-ahead reads 499,
SQL Server Execution Times: CPU time = 78 ms, elapsed time = 852 ms.
很明显,两者之间几乎没有任何区别 - 并且可能有一个微小的细节使得查询优化器更喜欢索引搜索扫描。不知道为什么 - 但我没有看到任何问题或问题。你呢?