假如我们有一张客户表:
- create table Customer
- (
- Id int primary key identity(1,1),
- CustName nvarchar(200),
- CustType int,
- CompanyName nvarchar(200),
- Phone varchar(20),
- CreateOn Datetime,
- CreateUserId int
- )
现在我们需要根据CustType、CreateOn、CreateUserId这三个字段来查询这张表,那我们可以这样来建索引:
create index Ix_Type_CreateOn_UserId on [dbo].[Customer](CustType,CreateOn,CreateUserId)
在where语句中这三个查询字段出现的顺序没有先后的区别,无论哪个字段在第一个都没关系。
现在我们把CustType这个字段从where查询中去掉,只根据CreateOn、CreateUserId这2个字段查询,那这个查询是不会用到这个索引的。
那我们怎么看这个查询有没有用到这个索引呢?打开SSMS,新建查询,把查询语句复制到这个查询窗口中,在SSMS工具栏上有2个按钮
第一个是显示预估的执行计划,第二个是包括实际的执行计划
显示预估的执行计划点击后,系统会根据当前查询所涉及到的所有表的统计信息生成查询的执行计划;包含实际的执行计划是要执行查询才能看到的执行计划,是系统实际执行的执行计划。简言之,第一个是系统预估的,第二个是系统实际执行的
我们点击第一个按钮,结果如图:
这里的执行计划用的不是上面那个查询的执行,只是想让大家看一下执行计划的结构。
我们看到执行计划里有一个Index Seek,这个是索引查找,是索引效率最高的一种。
把鼠标放到Index Seek上面,会显示这个索引在这个查询中的具体情况
具体的执行计划的相关知识请大家去网上查询,这不是本篇博客的主题
去掉最左边的CusType字段后,你再点击一下显示预估的执行计划,应该可以看到之前的Index Seek变成了Index Scan,后者的查询效率比前者低很多。
索引最左匹配定义:在建立索引时,索引的第一个字段必须出现在where查询的筛选字段中,如果不在,则这个索引就不会应用到这个查询中,准确的说应该时不会被最高效率地应用。如果这个索引的其他字段出现在where条件中,那执行计划就是Index Scan,而不是Index Seek。
所以在建立索引的时候要把最常被查询的字段放在索引的第一个字段中。
提示:如果执行计划的显示不是按照我说的那样,那应该先把执行计划的缓存清理一下,清理执行计划缓存语句:DBCC FREEPROCCACHE。注意,这个语句不要在生产环境下使用。