>  기사  >  데이터 베이스  >  Select*一定不走索引是否正确?

Select*一定不走索引是否正确?

WBOY
WBOY원래의
2016-06-07 16:06:132593검색

走索引指的是:SQL语句的执行计划用到了1、聚集索引查找 2、索引查找 ,并且查询语句中需要有where子句 根据where子句的过滤条件,去聚集索引或非聚集索引那里查找记录 一张表只有一列的情况: 聚集索引 USE [tempdb] GO CREATE TABLE t1 ( id INT ) GO CREA

走索引指的是:SQL语句的执行计划用到了1、聚集索引查找 2、索引查找 ,并且查询语句中需要有where子句

根据where子句的过滤条件,去聚集索引或非聚集索引那里查找记录

一张表只有一列的情况:

聚集索引

\
 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 &#43; 1
     END

 SELECT * FROM [dbo].[t1] WHERE [id]=20
View Code

\

非聚集索引

\
 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 &#43; 1
     END

 SELECT * FROM [dbo].[t2] WHERE [id]=20
View Code

\

只有一列,肯定会走索引的


一张表有多列的情况

分三种情况:

1、只有聚集索引

2、只有非聚集索引

3、有聚集索引和非聚集索引


只有聚集索引

\
 --只有聚集索引
 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  ( '销售部'&#43;CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' )
         SET @i = @i &#43; 1
     END


 SELECT * FROM [dbo].[Department] WHERE [DepartmentID]=2
View Code

\

\

小结:

只有聚集索引的表:如果where后面不包括创建聚集索引的时候的第一个字段,就会使用聚集索引扫描

下面SQL语句会使用聚集索引查找,因为包括了创建聚集索引的时候的第一个字段

 SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12

只有非聚集索引

\
 --只有非聚集索引
 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  ( '销售部'&#43;CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' )
         SET @i = @i &#43; 1
     END
 
SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12
View Code

\

\

小结:

只有非聚集索引的表:如果where后面不包括创建非聚集索引的时候的第一个字段,就会使用表扫描或者索引扫描

下面SQL语句会使用非聚集索引查找,因为包括了创建非聚集索引的时候的第一个字段

 SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12


有聚集索引也有非聚集索引

\\ 复制代码
 --有聚集索引和非聚集索引
 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  ( '销售部'&#43;CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' )
         SET @i = @i &#43; 1
     END
View Code

\

\

\

小结:

有聚集索引和非聚集索引的表:如果where后面包括创建聚集索引的时候的第一个字段,就会使用聚集索引查找

如果where后面包括创建非聚集索引的时候的第一个字段但不包括创建聚集索引的时候的第一个字段,就会使用索引查找

如果where后面不包括创建非聚集索引的时候的第一个字段和不包括创建聚集索引的时候的第一个字段,就会使用聚集索引扫描

1 SELECT * FROM [dbo].[Department] WHERE [GroupName]='销售组'

\


总结

其实走不走索引,关键取决于where后面包括还是不包括

创建聚集索引的时候的第一个字段

创建非聚集索引的时候的第一个字段

跟select *没有关系的,select * 最大的影响就是额外的IO开销

像“键查找” ,“RID查找”这些运算符就是额外的开销

键查找:到聚集索引里找其他字段的值

RID查找:到堆表里找其他字段的值

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.