Select * 一定不走索引是否正確?,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尋找:到堆表裡找其他欄位的值
我的sql語句不走索引(Oracle協助)
用下面的寫法使用索引:
select /*+index(a03 a03_a306_index)*/
* from a03 where a306>1.5;
中間看起來像注釋的是ORACLE的HINTS,強制使用索引
不走索引問題很多,比如沒有做索引分析或者索引被無效化之類,太籠統了,不清楚怎麼回事
SQL 索引是針對select的還是針對where的
建議你在看一下索引的用途;當用where的,那都有用到,當是update deleted的時候,那涉及到的欄位也有,但是主要是查詢的時候用到