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


走索引指的是: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 + 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 + 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  ( '銷售部'+CAST(@i AS VARCHAR(200)), '中國你好有限公司XX分公司', '銷售組' )
         SET @i = @i + 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  ( '銷售部'+CAST(@i AS VARCHAR(200)), '中國你好有限公司XX分公司', '銷售組' )
         SET @i = @i + 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  ( '銷售部'+CAST(@i AS VARCHAR(200)), '中國你好有限公司XX分公司', '銷售組' )
         SET @i = @i + 1
     END
View Code

小結:

有聚集索引和非聚集索引的表:假設where后面包含創建聚集索引的時候的第一個字段。就會使用聚集索引查找

假設where后面包含創建非聚集索引的時候的第一個字段但不包含創建聚集索引的時候的第一個字段。就會使用索引查找

假設where后面不包含創建非聚集索引的時候的第一個字段和不包含創建聚集索引的時候的第一個字段,就會使用聚集索引掃描

1 SELECT * FROM [dbo].[Department] WHERE [GroupName]='銷售組'


總結

事實上走不走索引,關鍵取決於where后面包含還是不包含

創建聚集索引的時候的第一個字段

創建非聚集索引的時候的第一個字段

跟select *沒有關系的,select * 最大的影響就是額外的IO開銷

像“鍵查找” ,“RID查找”這些運算符就是額外的開銷

鍵查找:到聚集索引里找其它字段的值

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM