走索引指的是:SQL语句的运行计划用到了1、聚集索引查找 2、索引查找 ,而且查询语句中须要有where子句
依据where子句的过滤条件。去聚集索引或非聚集索引那里查找记录
一张表仅仅有一列的情况:
聚集索引
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
USE [tempdb] GO CREATE TABLE t1 ( id INT ) GO CREATE CLUSTERED INDEX CIX_T1 ON [dbo].[t1](ID ASC) GO DECLARE @I INT SET @I = 1 WHILE @I < 1000 BEGIN INSERT INTO [dbo].[t1] ( [id] ) SELECT @I SET @I = @I + 1 END SELECT * FROM [dbo].[t1] WHERE [id]=20
非聚集索引
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
USE [tempdb] GO CREATE TABLE t2 ( id INT ) GO CREATE NONCLUSTERED INDEX IX_T2 ON [dbo].[t2](ID ASC) GO DECLARE @I INT SET @I = 1 WHILE @I < 1000 BEGIN INSERT INTO [dbo].[t2] ( [id] ) SELECT @I SET @I = @I + 1 END SELECT * FROM [dbo].[t2] WHERE [id]=20
仅仅有一列,肯定会走索引的
一张表有多列的情况
分三种情况:
1、仅仅有聚集索引
2、仅仅有非聚集索引
3、有聚集索引和非聚集索引
仅仅有聚集索引
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
--仅仅有聚集索引 USE [tempdb] GO CREATE TABLE Department ( DepartmentID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, Name NVARCHAR(200) NOT NULL , GroupName NVARCHAR(200) NOT NULL , Company NVARCHAR(300) , ModifiedDate DATETIME NOT NULL DEFAULT ( GETDATE() ) ) DECLARE @i INT SET @i=1 WHILE @i < 100000 BEGIN INSERT INTO Department ( name, [Company], groupname ) VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' ) SET @i = @i + 1 END SELECT * FROM [dbo].[Department] WHERE [DepartmentID]=2
小结:
仅仅有聚集索引的表:假设where后面不包含创建聚集索引的时候的第一个字段,就会使用聚集索引扫描
以下SQL语句会使用聚集索引查找,由于包含了创建聚集索引的时候的第一个字段
SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12
仅仅有非聚集索引
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
--仅仅有非聚集索引 USE [tempdb] GO CREATE TABLE Department ( DepartmentID INT IDENTITY(1, 1) NOT NULL , Name NVARCHAR(200) NOT NULL , GroupName NVARCHAR(200) NOT NULL , Company NVARCHAR(300) , ModifiedDate DATETIME NOT NULL DEFAULT ( GETDATE() ) ) CREATE NONCLUSTERED INDEX IX_Department ON Department(DepartmentID ASC) DECLARE @i INT SET @i=1 WHILE @i < 100000 BEGIN INSERT INTO Department ( name, [Company], groupname ) VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' ) SET @i = @i + 1 END SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12
小结:
仅仅有非聚集索引的表:假设where后面不包含创建非聚集索引的时候的第一个字段。就会使用表扫描或者索引扫描
以下SQL语句会使用非聚集索引查找,由于包含了创建非聚集索引的时候的第一个字段
SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12
有聚集索引也有非聚集索引
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
--有聚集索引和非聚集索引 USE [tempdb] GO CREATE TABLE Department ( DepartmentID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, Name NVARCHAR(200) NOT NULL , GroupName NVARCHAR(200) NOT NULL , Company NVARCHAR(300) , ModifiedDate DATETIME NOT NULL DEFAULT ( GETDATE() ) ) CREATE NONCLUSTERED INDEX IX_Department ON Department(Company ASC) DECLARE @i INT SET @i=1 WHILE @i < 100000 BEGIN INSERT INTO Department ( name, [Company], groupname ) VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' ) SET @i = @i + 1 END
小结:
有聚集索引和非聚集索引的表:假设where后面包含创建聚集索引的时候的第一个字段。就会使用聚集索引查找
假设where后面包含创建非聚集索引的时候的第一个字段但不包含创建聚集索引的时候的第一个字段。就会使用索引查找
假设where后面不包含创建非聚集索引的时候的第一个字段和不包含创建聚集索引的时候的第一个字段,就会使用聚集索引扫描
1 SELECT * FROM [dbo].[Department] WHERE [GroupName]='销售组'
总结
事实上走不走索引,关键取决于where后面包含还是不包含
创建聚集索引的时候的第一个字段
创建非聚集索引的时候的第一个字段
跟select *没有关系的,select * 最大的影响就是额外的IO开销
像“键查找” ,“RID查找”这些运算符就是额外的开销
键查找:到聚集索引里找其它字段的值
RID查找:到堆表里找其它字段的值