ROW 사이즈에 따른 업데이트 성능에 대한 고민
[하나의 Row 사이즈가 50Byte일 경우]
|
-- 테이블생성 drop table tbl_A; create table tbl_A ( col_A int identity(1, 1) , col_B char (38) , col_C datetime ); insert into tbl_A(col_B, col_C) select '', getdate() from master.dbo.sysobjects; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; -- 클러스터인덱스생성 create unique clustered index PK_tbl_A on tbl_A(col_A) sp_spaceused tbl_A; name rows reserved data index unused tbl_A 940032 55048 KB 54896 KB 112 KB 40 KB DBCC SHOWCONTIG ('tbl_A') - 검색한페이지................................: 6862 - 검색한익스텐트..............................: 858 - 익스텐트스위치..............................: 857 - 익스텐트당평균페이지수........................: 8.0 - 검색밀도[최적:실제].......: 100.00% [858:858] - 논리검색조각화상태..................: 0.00% - 익스텐트검색조각화상태...................: 0.23% - 페이지당사용가능한평균바이트수.....................: 13.5 - 평균페이지밀도(전체).....................: 99.83% -- 컬럼추가 alter table tbl_A add col_D datetime null; -- 컬럼업데이트 set statistics io on update tbl_A set col_D = col_C + 1 set statistics io off -- 50 Byte 테이블'tbl_A'. 검색수1, 논리적읽기수75577, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0. (940032개행적용됨) DBCC SHOWCONTIG ('tbl_A') - 검색한페이지................................: 13723 - 검색한익스텐트..............................: 1725 - 익스텐트스위치..............................: 13722 - 익스텐트당평균페이지수........................: 8.0 - 검색밀도[최적:실제].......: 12.50% [1716:13723] - 논리검색조각화상태..................: 99.74% - 익스텐트검색조각화상태...................: 0.52% - 페이지당사용가능한평균바이트수.....................: 3506.5 - 평균페이지밀도(전체).....................: 56.68% sp_spaceused tbl_A; name rows reserved data index unused tbl_A 940032 110088 KB 109784 KB 288 KB 16 KB |
[하나의 Row 사이즈가 200Byte일 경우]
|
-- 테이블생성 drop table tbl_A; create table tbl_A ( col_A int identity(1, 1) , col_B char (188) , col_C datetime ); insert into tbl_A(col_B, col_C) select '', getdate() from master.dbo.sysobjects; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; -- 클러스터인덱스생성 create unique clustered index PK_tbl_A on tbl_A(col_A) sp_spaceused tbl_A; name rows reserved data index unused tbl_A 940032 198344 KB 197904 KB 336 KB 104 KB DBCC SHOWCONTIG ('tbl_A') - 검색한페이지................................: 24738 - 검색한익스텐트..............................: 3093 - 익스텐트스위치..............................: 3092 - 익스텐트당평균페이지수........................: 8.0 - 검색밀도[최적:실제].......: 100.00% [3093:3093] - 논리검색조각화상태..................: 0.00% - 익스텐트검색조각화상태...................: 0.13% - 페이지당사용가능한평균바이트수.....................: 154.1 - 평균페이지밀도(전체).....................: 98.10% -- 컬럼추가 alter table tbl_A add col_D datetime null; -- 컬럼업데이트 set statistics io on update tbl_A set col_D = col_C + 1 set statistics io off -- 200 Byte 테이블'tbl_A'. 검색수1, 논리적읽기수247841, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0. (940032개행적용됨) DBCC SHOWCONTIG ('tbl_A') - 검색한페이지................................: 49475 - 검색한익스텐트..............................: 6201 - 익스텐트스위치..............................: 49474 - 익스텐트당평균페이지수........................: 8.0 - 검색밀도[최적:실제].......: 12.50% [6185:49475] - 논리검색조각화상태..................: 99.27% - 익스텐트검색조각화상태...................: 0.18% - 페이지당사용가능한평균바이트수.....................: 3973.0 - 평균페이지밀도(전체).....................: 50.91% sp_spaceused tbl_A; name rows reserved data index unused tbl_A 940032 396808 KB 395800 KB 976 KB 32 KB |
위의 결과를 보면 50Byte에 비해서 대략 4배정도의 차이가 나는 것을 확인할 수 있다. (예상대로임)
[하나의 Row 사이즈가 500Byte일 경우]
|
-- 테이블생성 drop table tbl_A; create table tbl_A ( col_A int identity(1, 1) , col_B char (488) , col_C datetime ); insert into tbl_A(col_B, col_C) select '', getdate() from master.dbo.sysobjects; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; insert into tbl_A(col_B, col_C) select '', getdate() from tbl_A; -- 클러스터인덱스생성 create unique clustered index PK_tbl_A on tbl_A(col_A) sp_spaceused tbl_A; name rows reserved data index unused tbl_A 940032 502216 KB 501352 KB 824 KB 40 KB DBCC SHOWCONTIG ('tbl_A') - 검색한페이지................................: 62669 - 검색한익스텐트..............................: 7834 - 익스텐트스위치..............................: 7833 - 익스텐트당평균페이지수........................: 8.0 - 검색밀도[최적:실제].......: 100.00% [7834:7834] - 논리검색조각화상태..................: 0.01% - 익스텐트검색조각화상태...................: 0.13% - 페이지당사용가능한평균바이트수.....................: 461.0 - 평균페이지밀도(전체).....................: 94.30% -- 컬럼추가 alter table tbl_A add col_D datetime null; -- 컬럼업데이트 set statistics io on update tbl_A set col_D = col_C + 1 set statistics io off -- 500 Byte 테이블'tbl_A'. 검색수1, 논리적읽기수62772, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0. (940032개행적용됨) DBCC SHOWCONTIG ('tbl_A') - 검색한페이지................................: 62669 - 검색한익스텐트..............................: 7834 - 익스텐트스위치..............................: 7833 - 익스텐트당평균페이지수........................: 8.0 - 검색밀도[최적:실제].......: 100.00% [7834:7834] - 논리검색조각화상태..................: 0.01% - 익스텐트검색조각화상태...................: 0.13% - 페이지당사용가능한평균바이트수.....................: 341.0 - 평균페이지밀도(전체).....................: 95.79% sp_spaceused tbl_A; name rows reserved data index unused tbl_A 940032 502216 KB 501352 KB 824 KB 40 KB |
용량이 10배 증가하였는데 왜? 훨씬 적은 I/O가 발생하였을까요? ^^
이올린에 북마크하기
댓글을 달아 주세요
50byte인 경우 페이지 밀도가 99.83%이니 페이지당 약 160 row 미만이 저장되어있을테고, 8byte컬럼이 추가되면 해당 페이지에서 추가로 필요한 공간은 1280byte죠... 하지만 실제 여유 공간은 13.5byte뿐이므로... page가 split되면서 많은 I/O가 발생합니다.
200byte일때도 계산해보면 비슷한 상황이네요.
하지만, 500byte일 때는 한 페이지에 15개의 row가 들어가 있고, 컬럼 추가로 인해 새로 필요한 공간은 120byte입니다. 그런데 페이지 당 평균 341byte가 남아 있으니 page split이 발생하지 않습니다.
실제로 500byte인 경우 update 전/후의 페이지 수를 비교하면 62669로 동일하고, 페이지 밀도만 증가했음을 볼 수 있네요. ^^
자세한 설명 감사 드립니다. ^^