출처 :  http://blog.naver.com/PostView.nhn?blogId=waws01&logNo=60181424769&redirect=Dlog&widgetTypeCall=true



★ Best 실행계획은 Clustered Index Seek (Clustered) 이다!!!



====================================================================================

CREATE TABLE tmp_myfan

(

     fan_id   INT          NOT NULL                                           -- 고유값

   , fan_name NVARCHAR(20) NOT NULL                                           -- 날조아하는여학생명

   , fan_feel FLOAT        NOT NULL DEFAULT 0                                 -- 호감지수

   , fan_gift NVARCHAR(30)     NULL                                           -- 그녀들이내게한선물

   , fan_date VARCHAR(8)   NOT NULL DEFAULT CONVERT(CHAR(8), GETDATE(), 112)  -- 선물받은날짜

   , cr_date  DATETIME              DEFAULT GETDATE()                         -- 입력날짜

);

CREATE UNIQUE CLUSTERED INDEX ix_tmp_myfan ON tmp_myfan(fan_id, cr_date);  

====================================================================================




1) SELECT절과 WHERE절에 CLUSTERED INDEX 컬럼인 경우

====================================================================================

SELECT fan_id, cr_date FROM tmp_myfan WHERE fan_id = 110 ;

====================================================================================

=> 실행계획 : Clustered Index Seek (Clustered)


2) SELECT절에는 CLUSTERED INDEX 컬럼, WHERE절에는 index가 아닌 컬럼인 경우

====================================================================================

SELECT fan_id FROM tmp_myfan WHERE fan_feel > 95;

====================================================================================

=> 실행계획 : Clustered Index Scan (Clustered)     <-- 사실상 Table Scan과 다를 바가 없다고 함.


3) SELECT절에는 CLUSTERED INDEX 컬럼, WHERE절에는 index 컬럼인 경우

====================================================================================

CREATE INDEX ix_non_tmp_myfan ON tmp_myfan(fan_feel); -- fan_feel 컬럼에 인덱스 생성

SELECT fan_id FROM tmp_myfan WHERE fan_feel > 95;

====================================================================================

=> 실행계획 : Index Seek (NonClustered)


4) fan_feel에 인덱스 생성하고 4-1, 4-2의 경우

   4-1) 

   =================================================================================

   CREATE INDEX ix_non_tmp_myfan ON tmp_myfan(fan_feel); -- fan_feel 컬럼에 인덱스 생성


   SET SHOWPLAN_ALL ON

   SELECT fan_feel FROM tmp_myfan WHERE fan_feel > 95 AND fan_id = 110;

   SET SHOWPLAN_ALL OFF


   |--Clustered Index Seek(OBJECT:([Test].[dbo].[tmp_myfan].[ix_tmp_myfan]), 

   SEEK:([Test].[dbo].[tmp_myfan].[fan_id]=(110)),  

   WHERE:([Test].[dbo].[tmp_myfan].[fan_feel]>(9.400000000000000e+001)) ORDERED FORWARD)

   =================================================================================

   => 해석 : ix_tmp_myfan 를 WHERE 순서를 무시하고 Clustered Index Seek 로 수행하고, 그때 행하고 ix_non_tmp_myfan 의 fan_feel는 필터링. 사실상 Seek시 범위를 줄여주지 못하는 상황.


   4-2) (4-1에 이어서..)

   =================================================================================

   SET SHOWPLAN_ALL ON



   |--Index Seek(OBJECT:([Test].[dbo].[tmp_myfan].[ix_non_tmp_myfan]), 

   SEEK:([Test].[dbo].[tmp_myfan].[fan_feel] > (9.800000000000000e+001)),  

   WHERE:([Test].[dbo].[tmp_myfan].[fan_id]>(110)) ORDERED FORWARD)

   =================================================================================

   => 해석 : ix_non_tmp_myfan 를 Index Seek 로 수행하고, 그때 행하고 ix_tmp_myfan 의 fan_id는 필터링. 역시나 데이터량이 많은 경우라면 특단의 조치가 필요한 상황.


5) fan_feel에 인덱스 생성하고 다음의 경우

====================================================================================

CREATE INDEX ix_non_tmp_myfan ON tmp_myfan(fan_feel); -- fan_feel 컬럼에 인덱스 생성


SET SHOWPLAN_ALL ON

SELECT fan_feel FROM tmp_myfan WHERE fan_feel = 99 AND fan_id > 110;

SET SHOWPLAN_ALL OFF



|--Index Seek(OBJECT:([Test].[dbo].[tmp_myfan].[ix_non_tmp_myfan]), 

SEEK:([Test].[dbo].[tmp_myfan].[fan_feel]=CONVERT_IMPLICIT(float(53),[@1],0) 

AND [Test].[dbo].[tmp_myfan].[fan_id] > CONVERT_IMPLICIT(int,[@2],0)) ORDERED FORWARD)

====================================================================================

=> 해석 : 아주 Best한 결과!! 

ix_non_tmp_myfan 를 Index Seek 로 수행할 때 ix_tmp_myfan 의 fan_id 를 NON LEAF LEVEL에 포함시켜 버린다. 

NONCLUSTERED INDEX 가 NON UNIQUE하고 포함된 COLUMN이 WHERE 절에서 등호(=)로 조회할때 

위와 같이 CLUSTERED INDEX CLUSTERING KEY가 NONCLUSTERED INDEX 의 NON LEAF LEVEL에 포함되게 된다.



6) SELECT 절에 index가 아닌 fan_name을 추가하여 조회한 경우

====================================================================================

SELECT fan_id, fan_name FROM tmp_myfan WHERE fan_feel > 95;

====================================================================================

=> 실행계획 : Clustered Index Scan (Clustered)

=> 해석 : fan_name과 같이 필요없는 컬럼을 함부로 조회하게 되면, 성능이 급격하게 저하된다.




+ Recent posts