SQL Leader 에서 재미있는 이슈가 있어 간단히 테스트한 내용을 옮겨둠~
http://www.sqlleader.com/mboard.asp?exec=view&strBoardID=SS2005QNA&intPage=2&intCategory=0&strSearchCategory=|s_name|s_subject|&strSearchWord=&intSeq=2369
결국 질문에 대한 답은 아니었지만 한가지 알게 되었으니 기념으로!! ^^

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

DB에 데이터가 들어가면 내부적으로 페이지를 할당하게 됩니다.
반대로 데이터가 삭제될 경우 삭제 즉시 할당된 페이지가 반환되는게 아니라 비동기적으로 반환이 이루어지는것 같습니다.

자.. 이제 쭈아님께서 작업하시는 스토리대로 예제를 한번 만들어 보겠습니다.

예를들어 테이블에 1 ~ 1000 까지 데이터를 넣어서 1000개의 페이지가 할당되었다고 가정하고,
(사실 1페이지에는 더 많은 데이터가 들어가겠지만 계산을 쉽게 하기 위해.. ^^; )

먼저 SELECT를 해보면 정상적으로 읽기가 수행이 됩니다.

하지만 1~900까지를 삭제한 다음 잽싸게 다시 SELECT를 해보면..
ASC로 읽었을때 훨씬 많은 페이지를 읽게 됩니다.
데이터가 삭제되어서 없지만 유령 페이지가 남아있어서 실제 데이터가 나올때까지 순차적으로 읽어나가게 됩니다.
(앞쪽 데이터를 삭제해서 앞쪽에 유령 페이지가 우루루 몰려 있는 상황입니다.)

물론 몇초후 다시 조회를 해보면 할당된 페이지를 반환하고 정상적인 조회가 이루어 지는것을 확인할 수 있습니다.


아래는 테스트에 사용한 쿼리를 간략하게 정리한 내용입니다.


그럼 좋은 하루 되세요~!
 

use master

-- drop database db2

create database db2

 

use db2

 

-- drop table tbl

create table tbl (col1 int, col2 char(8000))

create clustered index ci_col1 on tbl (col1)

 

insert into tbl

select top 1000 row_number() over (order by (select 1)) , 'a'

from sysindexes a, sysindexes b, sysindexes c

 

 

set statistics io on

 

select top 5 * from tbl with(nolock) order by col1 asc

select top 5 * from tbl with(nolock) order by col1 desc

 

 

(5개행적용됨)

테이블'tbl'. 검색수1, 논리적읽기수10, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

(5개행적용됨)

테이블'tbl'. 검색수1, 논리적읽기수9, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

-- 삭제후 잽싸게 SELECT 해본다

delete tbl where col1 < 900

 

select top 5 * from tbl with(nolock) order by col1 asc

select top 5 * from tbl with(nolock) order by col1 desc

 

(5개행적용됨)

테이블'tbl'. 검색수1, 논리적읽기수910, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

(5개행적용됨)

테이블'tbl' 검색수1, 논리적읽기수9, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

 

select top 5 * from tbl order by col1 asc

select top 5 * from tbl order by col1 desc

 

(5개행적용됨)

테이블'tbl'. 검색수1, 논리적읽기수910, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

(5개행적용됨)

테이블'tbl'. 검색수1, 논리적읽기수9, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

 

dbcc ind (DB2, tbl, -1)

 

-- 몇초후~ 다시해보면!!!! 오오~

 

(5개행적용됨)

테이블'tbl'. 검색수1, 논리적읽기수11, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

(5개행적용됨)

테이블'tbl'. 검색수1, 논리적읽기수10, 물리적읽기수0, 미리읽기수0, LOB 논리적읽기수0, LOB 물리적읽기수0, LOB 미리읽기수0.

 

AND