我为什么要索引?

时间:2012-07-14 20:37:41

标签: sql-server tsql indexing

我在查询下面运行,因为它几乎从表中返回所有记录,它应该使用索引扫描而不是查找。任何人,请解释为什么它使用搜索而不是扫描。


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

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.
很明显,两者之间几乎没有任何区别 - 并且可能有一个微小的细节使得查询优化器更喜欢索引搜索扫描。不知道为什么 - 但我没有看到任何问题或问题。你呢?