此时若我们将查询条件进行如下修改。
USE TSQL2012
GO
SELECT orderid, shipaddress, shipregion
FROM Sales.Orders
WHERE shipaddress = '深圳'
GO
到这里我们应该发现了,唯一的区别在于我们创建非聚集索引时的顺序和查询条件不同就会导致索引扫描和索引查找的转换,那么到底什么时候才会执行索引查找呢?我们可以进行如下一般性总结:
索引查找的一般性结论:如果条件中包含WHERE或者ON的话,查询条件必须是位于索引集合列中首位,此时索引查找将会被使用。
此时我们穿插一点内容,上述我们创建了覆盖索引,我们来比较下覆盖索引和默认情况下聚集索引查找的性能开销。
覆盖索引与默认聚集索引性能开销比较
FROM Sales.Orders WITH(INDEX([PK_Orders]))
WHERE orderid<11072
go
SELECT orderid, shipaddress, shipregion
FROM Sales.Orders WITH(INDEX([idx_noncls_include_exceptorderid]))
WHERE orderid<11072
GO
从上可知,覆盖索引的开销要比默认主键聚集索引性能开销要好一点,同时我们可以看看如下二者IO代价。


通过上述覆盖索引与默认聚集索引的对比,我们能够有效的减少IO,这一点也是非常明确的,当然下面的INCLUDE索引对比也是另外一种好的方案。

创建INCLUDE非聚集索引
USE TSQL2012
GO
CREATE NONCLUSTERED INDEX [ix_noncls_include] ON [TSQL2012].[Sales].[Orders] (
shipcity
) INCLUDE (shipaddress, shipregion, orderid)
至此我们用两种方式来移除了Bookmark Lookup、RID Lookup、Key Lookup,通过使用索引和覆盖索引。
既然有如上两种方式,我们应该有所取舍,二者谁的性能更好呢?我们接下来比较上述二者的开销差异。
比较移除Bookmark Lookup等两种方式差异
USE TSQL2012
GO
SELECT orderid, shipaddress, shipcity, shipregion










