MS-SQL Server

순차 미리 읽기

고희수 2011. 2. 24. 17:23
오늘 다룰내용은 순차 미리 읽기 입니다.

미리 읽기는 쿼리 실행 계획을 수행하는 데 필요한 데이터 및 인덱스 페이지를 예상하고 페이지가 쿼리에서 실제로 사용되기 전에 가져오는 작업을 말합니다. 대부분 (대량)범위검색 및 테이블스캔, 통계 재작성등 예상이 가능한 조건들에서
미리읽기가 발생합니다. 예를들면 이런거죠.
대량의 순차데이터 검색시 " 앞에 데이터도 필요하겠는걸, 온김에 미리 가져가야지.."

아래는 미리읽기와 관련된 기반지식입니다.

CPU와 I/O 처리량의 균형은 하드웨어 활용도를 높이는 필수적인 사항인데요.
디스크 I/O가 CPU 처리수용량을 능가해서도, 부족해서도 안됩니다. 불균형시 시스템 낭비로 이어질수 있기 때문입니다.(물론 시스템특성상 그렇지 않은 경우도 다수 존재합니다.)

또한 비동기 I/O처리가 왜 중요한지 이해하기 위해서, CPU의 I/O성능 차이도 이해해야 합니다.
요즘은 CPU상의 메모리에서 소켓당 대략 5Gbyte(초당) 데이터를 순차처리 한다고 합니다.
즉, 초당 10~50,000,000의 메모리 위치를 액세스 할 수 있다는 얘기가 됩니다. 메모리.. 확실이 빠릅니다.

디스크의 경우 하이엔드급인 15000rpm SAS디스크는 125Mbyte/sec 순차적으로 읽을수있고 랜덤 I/O액세스가
200 IOPS 입니다. 물론 SSD(Solid State Disk)는 일반 디스크와 처리방식의 차이로 훨씬 더 빠르죠.

이처럼 디스크 액세스와 메모리 액세스는 엄청난 차이가 납니다. 때문에 미리읽기를 이용해
디스크에서 메모리로 데이터를 적재시키는 작업 및 횟수를 줄이는게 얼마나 의미있는 작업인지 알수 있습니다.
다만 미리읽기로 인해 예상하는 데이터가 정확히 일치않아 불필요한 데이터가 메모리에 적재될수 있습니다.

그럼 미리읽기가 어떻게 처리되는지 알아보겠습니다.

하나의 CPU는 한번에 하나의 spindle(회전축)을 실행시켜 I/O 동기화처리를 합니다.
일반적으로 데이터를 읽고나서 연산을 하는 과정으로 읽기 및 연산 동시수행은 안됩니다.
하지만 CPU가 사용가능한 대역폭 및 IOPS를 최대한 활용하기 위해서 다중 비동기 I/O처리를 해야하는데요.
미리읽기에서는 여러 쓰레드에 읽기요청을 보내고 읽어들이는 순서대로 계속 연산을 할수있어 동시수행처럼 처리합니다.
(이부분 확신이 안섭니다.^^;)

미리읽기에는 데이터페이지 읽기와 인덱스 페이지 읽기가 있는데요.이 둘의 차이는

정렬된 할당스캔(데이터페이지 읽기) 은 물리적으로 저장된 순서대로 페이지를 읽으려 합니다.
즉 IAM페이지로 읽을경우 익스텐트단위로 할당된 물리적 주소를 결정해 정렬하고 다른 쓰레드로 비동기로
순차읽기를 진행해 I/O작업을 최적화 합니다.

정렬된 인덱스 스캔은 저장된 인덱스페이지의 데이터를 순서대로 읽습니다.
인덱스의 Non-Leaf 페이지에서 읽어야할 키값을 기준으로 키를 포함하는 (leaf)페이지 및 다음 (leaf)페이지들을
확인하고 Leaf페이지들을 읽습니다. 이역시 다른 쓰레드로 비동기로 읽어들입니다.

데이터페이지의 경우 IAM페이지로, 인덱스의 경우 Non-Leaf페이지에서.. 즉 읽을 페이지의 상위수준에서
미리 읽어들일(다음에 필요한) 페이지를 확인합니다.