Posted by 디오디오

DAT 412 
Tech-Ed 97에 소개됨

Adam Shapiro 
Program Manager 
Microsoft Corporation

개요

SQL Server 구성 정보

Microsoft® SQL Server™는 SQL Server를 구성하기 위한 많은 옵션을 제공하며 SQL Server의 동작에 영향을 미칩니다. 3부에서는 이와 관련된 중요한 옵션에 대해 설명합니다.

조직의 하드웨어 환경에 맞게 조정해야 하는 몇 가지 옵션을 제외하고 대부분의 옵션은 전혀 조정할 필요가 없습니다.

시스템 구성 정보는 sysconfigures, syscurconfigs, 구성 블록 및 Windows NT 레지스트리에 저장됩니다.

sysconfigures

이 시스템 테이블에는 사용자가 설정할 수 있는 각 구성 옵션에 대한 행이 있습니다. 이 테이블에는 가장 최근에 SQL Server를 시작하기 전에 정의한 구성 옵션 그리고 가장 최근에 SQL Server를 시작한 이후 설정한 동적 구성 옵션이 있습니다.

syscurconfigs

이 시스템 테이블에도 sysconfigures와 마찬가지로 각 구성 옵션에 대한 항목이 있지만 현재 값이 포함된다는 것이 다릅니다. 또한, 이 테이블에는 구성 구조를 기술하는 4개의 항목이 있습니다.

이 테이블은 sysobjects에 테이블로 표시되지만 실제로는 사용자가 쿼리할 때만 만들어지는 의사 테이블입니다. syscurconfigs에 대해 sysindexes 행이 보이면 데이터 행이 전혀 없다는 뜻입니다.

SQL 엔터프라이즈 관리자를 사용하거나 sp_configure 시스템 저장 프로시저를 실행하여 구성 값을 변경할 수 있습니다. sp_configure를 실행하여 구성 옵션을 변경하는 경우 뒤이어 RECONFIGURE 문을 사용해야 합니다. SQL 엔터프라이즈 관리자가 자동으로 RECONFIGURE 문을 실행합니다.

구성 블록

RECONFIGURE 문은 변경된 구성 옵션을 설치합니다. 이는 syscurconfigs 테이블의 내용이 마스터 장치의 처음 네 페이지에 쓰인다는 뜻입니다. 이들 페이지를 구성 블록이라고 합니다. 다음 번에 SQL Server를 시작할 때 마스터 장치에서 sysconfigures 테이블로 값을 읽어들일 수 있습니다.

Windows NT 레지스트리

SQL Server를 시작하면 SQL Server가 마스터 장치에서 구성 블록을 읽습니다. 마스터 장치는 Microsoft Windows NT® 레지스트리에서 찾을 수 있습니다.

SQL Server 메모리 및 I/O 관리

조정할 수 있는 가장 중요한 한 가지 구성이 SQL Server에 할당된 메모리 양일 것입니다.

SQL Server 메모리 사용

전역 리소스

전역 리소스는 모든 프로세스와 데이터베이스가 사용하는 리소스입니다. 전역 리소스 영역은 대부분 서버에 정의된 각 데이터베이스를 제어하는 구조 등의 다른 구조, 페이지와 확장 영역 그리고 프로시저에 대한 해시 테이블, 서버 차원의 문자 집합 및 정렬 순서에 대한 정보 등을 가리키는 포인터입니다. 이 영역에는 SQL Server에 대한 실행 가능 코드도 포함됩니다.

사용자 연결

각 사용자 연결은 서버 구조에 대략 27K 그리고 ODS 구조에 3K 등 총 30K의 SQL Server 메모리를 필요로 합니다. 이 메모리는 PSS(프로세스 상태 구조), 트랜잭션 설명자, 세션 설명자, 보호 캐시, 로그인 레코드, 파서 작업 영역에 사용되며 이들 모두 초기화 시에 SQL Server가 만드는 힙에서 할당됩니다.

또한, 사용자 연결에 1MB의 글로벌 스택이 예약되지만 이 메모리는 즉시 커밋되지 않습니다. SQL Server를 실행하는 동안 더 많은 스택 공간이 필요하면 최고 1MB까지 추가 메모리가 커밋됩니다. 신규 스레드(실제로 사용되고 있는 사용자 연결)마다 스택 공간의 20K 정도를 필요로 합니다.

따라서 각 사용자 연결은 max worker threads 한계까지 총 50K를 필요로 합니다. 그 후에는 연결마다 30K가 필요합니다.

잠금, 열린 데이터베이스, 열린 개체

잠금, 열린 데이터베이스, 열린 개체에는 각각의 구성 값을 기반으로 메모리가 할당됩니다. 아래 값을 사용하여 이들 옵션의 총 메모리 소모량을 측정할 수 있습니다.

잠금 
60바이트 
열린 데이터베이스 
162바이트 
열린 개체 
240바이트 

시스템의 실제 메모리 사용 상태에 대한 추가 정보를 보려면 DBCC MEMUSAGE를 실행하기 전에 추적 플래그 3635를 활성화하십시오.

프로시저 및 데이터 캐시

프로시저와 데이터 캐시에 대해서는 이 문서의 뒷부분에서 자세히 설명합니다.

메모리 관련 구성 옵션

 

Memory

이 구성 옵션은 사용 가능한 메모리의 크기를 2K 단위로 설정합니다. 초기 값은 컴퓨터의 메모리 양을 기반으로 설치 프로그램이 결정합니다.

시스템에 맞게 이 값을 최적화하려면 전체 실제 메모리에서 Windows NT에 필요한 메모리 그리고 SQL Server 전용 컴퓨터가 아닌 경우 다른 시스템이 사용하는 메모리를 뺍니다.

이상적으로는 시스템의 페이징 동작을 유발하지 않고 SQL Server에 최대한 많은 메모리를 할당하는 것이 좋습니다. Windows NT 성능 모니터를 사용하면 시스템에 대한 임계값을 결정하는 데 도움이 됩니다. 메모리 개체의 Page Faults/sec 카운터는 페이지 부재가 발생하는지 여부를 나타냅니다. 페이지 부재가 발생한다면 SQL Server가 지나치게 많은 메모리를 사용하여 실행되고 있는 것입니다. 임계값은 시스템에 따라 달라집니다.

아래 표는 SQL Server 메모리 할당 시의 적절한 시작 값을 제시한 것입니다. 이 값들은 SQL Server 전용 시스템에 사용한다는 가정 하에 제안하는 수치입니다.


RAM(MB) 
SQL Server 메모리 할당(MB 단위) 
SQL Server 메모리 할당(2K 단위) 
16
4
2,048
24
8
4,096
32
16
8,192
64
40
20,480
128
100
51,210
256
216
110,592
512
464
237,568

이 값은 시스템에 메모리를 추가하거나 제거하는 경우 또는 시스템 용도를 바꾸는 경우에만 변경해야 합니다.

메모리 옵션을 다시 구성하면 free buffers 구성 옵션도 자동으로 변경됩니다. free buffers 구성 값은 신규 메모리 크기의 5%로 설정됩니다. 이 값의 의미에 대해서는 뒤에서 설명합니다.

memory 옵션의 최대값은 2GB입니다. 그러나 tempdb in RAM 옵션을 사용하여 RAM에 tempdb를 배치한 경우, memory 옵션에 tempdb에 대한 메모리 요구가 포함되지 않습니다.

Open Databases

이 구성 옵션은 SQL Server에서 한 번에 열 수 있는 최대 데이터베이스 수를 설정합니다. 기본값은 20입니다. 열린 데이터베이스는 메모리를 사용하기 때문에 이 값을 늘리면 SQL Server 전용 메모리의 양도 늘려야 할 수 있습니다.

Open Objects

이 구성 옵션은 SQL Server에서 한 번에 열 수 있는 최대 데이터베이스 개체 수를 설정합니다. 기본값은 50입니다.

SQL Server가 열린 개체 수를 초과했다는 메시지를 표시하면 이 값을 늘려야 합니다. 열린 개체는 메모리를 사용하기 때문에 이 값을 늘리면 SQL Server 전용 메모리의 양도 늘려야 할 수 있습니다.

User Connections

이 구성 옵션은 SQL Server에 동시에 연결할 수 있는 최대 연결 수를 설정합니다. 데이터베이스 환경에 따라, 실제로 연결할 수 있는 개수는 이 값보다 적을 수도 있습니다.

허용되는 사용자 연결 수는 버전에 따라 달라집니다. SQL Workstation에서는 15이고 SQL Server에서는 32,767입니다. 그러나 실제 수는 응용 프로그램 및 하드웨어에 따라 달라지는 실제 한계를 기반으로 정해집니다.

아래 문을 사용하면 시스템에서 사용할 수 있는 최대 사용자 연결 수에 대한 보고서를 받을 수 있습니다.

SELECT @@max_connections 

각 사용자에게 허용할 연결 수를 결정하기 위한 공식은 없습니다. 연결 수는 시스템 및 사용자 요구 사항에 따라 설정해야 합니다. DB-Library 또는 ODBC 응용 프로그램을 실행하는 사용자들이 한 응용 프로그램에서 여러 연결을 열 수도 있습니다. 많은 사용자가 있는 시스템에서는 사용자들이 가끔씩만 필요한 연결을 공유할 가능성이 높습니다.

Locks

이 구성 옵션은 사용 가능한 잠금 수를 설정합니다. 잠금은 열린 데이터베이스 및 데이터베이스 개체의 공유 방식으로 공유되지 않습니다. 기본값은 5,000입니다.

SQL Server가 사용 가능한 잠금 수를 초과했다는 메시지를 표시하면 이 값을 늘려야 합니다. 잠금마다 32바이트의 메모리가 사용되기 때문에 이 값을 늘리면 SQL Server 전용 메모리의 양도 늘려야 할 수 있습니다.

Procedure Cache

이 구성 옵션은 SQL Server의 메모리 요구 사항이 충족된 후 프로시저 캐시에 할당되는 메모리 백분율을 지정합니다. SQL Server에 필요한 메모리는 잠금, 열린 데이터베이스, 열린 개체, 사용자 연결, 코드 자체 및 전역 리소스에 필요한 메모리를 합한 양입니다. 나머지 메모리는 이 구성 옵션으로 설정한 백분율에 따라 프로시저 캐시와 데이터 캐시 간에 분할됩니다.

프로시저 캐시는 가장 최근에 사용된 프로시저가 저장된 메모리 영역을 말합니다. 프로시저 캐시는 프로시저를 만들 때 그리고 쿼리를 컴파일할 때도 사용됩니다. 프로시저 캐시 구성 옵션의 기본값은 30입니다. 이 기본값은 SQL Server 요구 사항이 충족된 후 나머지 메모리의 30%를 프로시저 캐시에 할당합니다. 그리고 나머지 70%는 데이터 캐시가 사용합니다.

이 구성 옵션의 최적 값은 응용 프로그램마다 다르므로 이 값을 다시 설정하면 SQL Server의 성능을 향상시킬 수 있습니다. 예를 들어, 서로 다른 많은 프로시저 또는 임의 쿼리를 실행하는 경우, 응용 프로그램이 프로시저 캐시를 더 많이 사용할 것이므로 사용자가 이 값을 늘리고자 할 수 있습니다. 개발 과정에 있는 많은 응용 프로그램이 이 범주에 속합니다.

데이터 캐시 적중률을 높이기 위해 메모리를 추가하는 경우 프로시저 캐시의 크기가 비교적 일정하게 유지되도록 프로시저 캐시의 백분율이 낮아질 수 있습니다.

DBCC MEMUSAGE

DBCC MEMUSAGE

DBCC 문의 MEMUSAGE 옵션은 메모리 사용에 관한 자세한 보고서를 제공합니다. 이 옵션은 아래와 같은 세 종류의 정보를 제공합니다.

  • 시작할 때 서버 메모리가 할당된 방식
  • 버퍼 캐시의 가장 큰 개체 20개가 사용하는 메모리 양
  • 저장 프로시저, 트리거, 뷰, 규칙, 기본값 같은 저장 프로시저의 가장 큰 개체 20개가 사용하는 메모리 양

프로시저 캐시에 개체의 복사본이 여러 개 있으면 DBCC MEMUSAGE는 이들이 사용하는 메모리를 모두 합하여 총 메모리를 산출합니다. 이들 복사본 중 일부는 미리 컴파일된 개체 버전(트리)일 것이고 일부는 컴파일된 버전(계획)일 것입니다. DBCC MEMUSAGE는 트리와 계획의 크기를 비롯하여 캐시에 포함된 이들의 총 개수를 표시합니다.

tempdb in RAM

tempdb 데이터베이스는 일부 조인 작업에서 임시 테이블을 만들고 정렬하기 위한 작업 공간으로 사용됩니다. 또한 프로그래머들이 명시적 임시 테이블이나 임시 저장 프로시저를 만들 때도 이 테이터베이스가 사용됩니다.

tempdb in RAM 구성 옵션은 tempdb가 완전히 메모리 상주 데이터베이스가 될 수 있도록 합니다. 이를 통해 일부 특정한 상황에서 성능 이점을 얻을 수 있습니다. 그러나 tempdb in RAM을 잘못 사용하면 SQL Server 데이터 캐시에 사용되어야 할 메모리가 이 구성 옵션에 사용되어 성능이 떨어질 수 있습니다.

대부분의 경우, 사용 가능한 RAM은 tempdb의 위치가 아닌 데이터 캐시에 사용되는 것이 가장 좋습니다. tempdb의 데이터는 SQL Server 데이터 캐시의 LRU(최근에 사용되지 않은 것부터 사용) 알고리즘을 사용하여 캐시에 저장됩니다.

tempdb in RAM을 사용하면 tempdb 동작 속도가 빨라질 수 있지만 SQL Server 데이터 캐시에 사용할 수 있는 메모리가 적어지기 때문에 캐시 적중률이 낮아질 수 있습니다.tempdb in RAM에 사용되는 메모리는 memory 옵션으로 설정한 풀 집합과는 별도로 할당되므로 그에 맞게 서버를 구성해야 합니다.

예를 들어, tempdb in RAM에 100MB를 사용하는 경우 여기에 필요한 메모리를 확보하기 위해 memory 설정으로 할당한 메모리를 100MB 줄여야 할 것입니다. 이와는 반대로,tempdb in RAM에 메모리를 할당하지 않고 사용 가능한 모든 메모리를 SQL Server에 할당하면 캐시 적중률을 높일 수 있습니다. SQL Server는 tempdb와 관련된 동작을 포함하여 모든 디스크 I/O 동작을 캐시에 저장합니다.

여러 시스템에서 사용할 수 있는 RAM이 제한된 경우 tempdb가 RAM에 있으면 tempdb에 허용되는 크기가 제한됩니다. tempdb에 대해 예기치 않은 확장 요구 사항이 생기면 이것이 문제가 될 수 있습니다. 이런 우려가 있는 경우 RAM에 tempdb를 두지 마십시오.

일반적으로, 사용 가능한 RAM을 SQL Server 데이터 캐시에 사용하는 것이 tempdb in RAM에 대량의 메모리를 사용하는 것보다 낫습니다. 그러나 아래의 모든 조건이 성립되는 경우에는 tempdb in RAM을 사용하는 것이 효과적입니다.

  • 사용 가능한 시스템 RAM이 아주 많은 경우. 이는 일반적으로 64MB 이상을 뜻하며 128MB 이상이 더 일반적입니다.
  • 사용 가능한 데이터 캐시가 많이 있는데도 응용 프로그램이 SQL Server 캐시 적중률이 낮은 참조 위치를 가진 경우
  • 응용 프로그램이 많은 tempdb 작업을 수행하는 경우. 성능 모니터를 사용하면 tempdb의 크기를 관찰할 수 있습니다. SQL Server 개체에 대해서는 Max TempDB Space Used(MB) 카운터를 모니터할 수 있습니다. 이 카운터는 SQL 성능 모니터 세션 동안 tempdb 데이터베이스에 사용된 최대 메모리 양(MB)을 보고합니다.
  • RAM 구성에 의해 설정된 tempdb 크기에 맞도록 tempdb 작업의 크기가 조정되는 경우

RAM에 tempdb를 배치하기로 결정한 경우 이를 통해 얻을 수 있는 성능 이점을 객관적으로 검토하는 것이 좋습니다. 이를 위해 아래 작업을 수행합니다.

  1. 가장 자주 수행되는 tempdb 집중형 작업을 대표하는 단일 쿼리 또는 작은 쿼리 집합을 선택합니다.
  2. 이들 쿼리를 여러 번 실행하면서 실행 시간을 확인합니다.
  3. RAM의 tempdb를 다시 구성한 다음 같은 쿼리를 실행하여 그 차이를 확인합니다.

성능이 별로 향상되지 않은 경우 RAM을 SQL Server 데이터 캐시에 반환하는 것이 좋습니다.

RAM에 tempdb를 배치하는 것은 위험하지 않으며 데이터베이스 무결성이나 복구 가능성에 나쁜 영향을 미치지 않습니다. 이는 tempdb가 중간 작업에만 사용되고 각 서버를 다시 시작할 때 완전히 재구성되기 때문입니다.

tempdb in RAM 옵션은 분석을 통해 그 유용성이 확인된 경우에 사용할 수 있는 중요한 성능 향상 도구입니다. 이 옵션을 사용하여 성능을 많이 향상시킬 수도 있지만 무분별하게 사용해서는 안 됩니다.

tempdb in RAM 변경

RAM의 tempdb를 포함하여 tempdb 데이터베이스를 확장할 수 있습니다. 그러나 서버를 종료했다 다시 시작하지 않고 RAM에 배치된 tempdb를 변경할 수 있는 횟수는 10회뿐입니다. RAM에 있는 tempdb를 변경하면 데이터베이스가 변경될 때마다 새로운 인접 메모리 "청크"가 tempdb에 할당됩니다. 인접해 있기는 하지만 이 메모리가 반드시 RAM에 있는tempdb의 기존 부분 옆에 배치되는 것은 아닙니다. 최적의 성능을 얻으려면 tempdb를 변경한 후 서버를 종료하고 다시 시작해야 합니다.

RAM에서 tempdb 제거

구성 값을 다시 0으로 설정하여 RAM에서 tempdb를 제거할 수 있습니다. 이렇게 하면 기본 크기 2MB를 가진 tempdb가 기본 장치에 생성됩니다.

참고 업그레이드할 때 tempdb가 RAM에 있으면 곧 RAM에서 tempdb가 제거됩니다. tempdb를 만들려면 기본 디스크 장치에 최소한 2MB의 사용 가능한 메모리가 있어야 합니다. 그렇지 않으면 SQL Server가 시작되지 않습니다. 임시로 RAM에 2MB의 tempdb를 만들려면 명령줄에서 SQLSERVR.EXE와 함께 /f 플래그를 사용합니다.

SQL Server 데이터 캐시

데이터 캐시는 디스크에서 읽어들인 페이지를 보관하는 데 사용되는 버퍼 또는 페이지 프레임 집합입니다. 데이터 캐시는 SQL Server에 할당된 메모리에 포함됩니다. 또한 데이터 캐시를 페이지 캐시 또는 버퍼 캐시라고도 합니다.

조정할 수 있는 가장 중요한 한 가지 구성이 SQL Server에 할당된 메모리 양일 것입니다. 이는 데이터 캐시 양이 할당된 메모리 양에 정비례하기 때문입니다. 페이지가 데이터 캐시에 있느냐 그렇지 않느냐에 따라 페이지에 액세스할 때 물리적 읽기가 이루어는지 여부가 결정되며, 디스크를 물리적으로 읽는 것은 SQL Server가 수행할 수 있는 작업 중 비용이 가장 많이 드는 작업에 속합니다.

지금부터 이 절에 사용되는 용어 몇 가지를 소개합니다.

커밋되지 않은 데이터 페이지

데이터 수정 문에 의해 변경되었지만 아직 디스크에 쓰이지 않은 데이터 페이지를 말합니다.

사용 가능한 페이지

어떤 프로세스도 사용하지 않는 커밋된 페이지를 말합니다.

최근에 사용되지 않은 것부터 사용/최근에 사용된 것부터 사용(LRU/MRU) 체인

최근에 사용되지 않은 것부터 최근에 사용된 것의 순서로 정렬한 연결된 페이지 목록을 말합니다.

버퍼 관리자 해시

SQL Server가 데이터 캐시의 페이지를 빨리 찾거나 이들이 캐시에 없다는 것을 확인할 수 있도록 데이터 캐시의 페이지가 해시됩니다. hash buckets 구성 옵션은 메모리의 데이터 캐시 버퍼에 페이지를 해시하는 데 사용될 "버킷" 수를 설정합니다. 해시 버킷 수가 많을수록 SQL Server가 참조된 페이지를 더 빨리 찾을 수 있습니다. 해시 버킷이 사용된 페이지 목록의 참조된 페이지에 아주 가깝게 해시된 다음 정확한 페이지를 찾을 때까지 체인을 통과하기 때문입니다.

목적은 특정 해시 버킷에 대한 체인 크기를 제한하는 것입니다. 버킷이 많을수록 체인이 더 짧아집니다. 적당한 수의 해시 버킷만 사용하면 대용량 데이터 캐시도 빠르게 검색할 수 있습니다.

예제

해시 버킷의 기본값은 약 8K입니다. 각 해시 버킷이 최적의 길이(4페이지)를 가진 경우 SQL Server는 아래와 같은 데이터 캐시 크기를 지원할 수 있습니다.

4 x 8K = 32K 페이지 = 64MB

최대 해시 버킷 수(256K)와 최적의 해시 체인 길이를 사용하면 SQL Server가 아래와 같은 데이터 캐시 크기를 지원할 수 있습니다.

4 x 256K = 1024K 페이지 = 2GB

체인 길이를 모두 4페이지 이내로 구성하는 것이 가장 좋습니다. 체인이 이보다 길면 hash buckets 구성 옵션의 값을 늘립니다.

이러한 해시 버킷은 메모리를 아주 조금밖에 사용하지 않으며 SQL Server는 해시 버킷의 실제 수를 입력된 값에 가장 가까운 수로 조정합니다. 기본값은 7,993개이고 최대값은 265,003개입니다.

DBCC BUFCOUNT를 사용하여 현재의 해시 구성이 얼마나 효율적인지 검사할 수 있습니다.

DBCC TRACEON(3604) 
GO 
DBCC BUFCOUNT 
GO 
**** THE 10 LONGEST BUFFER CHAINS **** 
bucket number = 20 chain size = 2 
bucket number = 276 chain size = 2 
bucket number = 532 chain size = 2 
bucket number = 1044 chain size = 2 
bucket number = 1300 chain size = 2 
bucket number = 1556 chain size = 2 
bucket number = 1812 chain size = 2 
bucket number = 2324 chain size = 2 
bucket number = 3092 chain size = 2 
bucket number = 3604 chain size = 2 
The Smallest Chain Size is: 0 
The Average Chain Size is: 0.671668 

검사점

검사점 시스템 프로세스

검사점 프로세스는 주로 절전 모드일 때 SQL Server에서 항상 실행되는 시스템 프로세스입니다. sp_who 프로시저를 실행하여 이를 확인할 수 있습니다. 검사점 프로세스는 1분마다 활성화되어 각 데이터베이스의 트랜잭션 로그를 검사합니다. 검사점 시스템 프로세스를 통해 마지막 검사점 이후 충분한 작업이 수행되었다는 것이 확인되면 SQL Server는 그 데이터베이스에 대해 다른 검사점을 지정합니다.

충분한 작업이 수행되었는지 여부는 recovery interval 구성 옵션 값으로 결정합니다. 이 값은 분 단위로 설정됩니다. 검사점 시스템 프로세스는 설정된 시간만큼의 복구 시간이 걸릴 정도로 충분한 트랜잭션이 로그에 있는지 확인합니다.

CHECKPOINT 문

CHECKPOINT 문은 DBO 또는 SA를 사용하여 수동으로 실행할 수 있습니다.

검사점 프로세스 동안 진행되는 작업

SQL Server는 검사점을 만들 때 커밋되지 않은 모든 데이터 페이지를 디스크에 씁니다. 검사점이 검사되는 데이터베이스의 페이지들을 빠르게 찾을 수 있도록 각 데이터베이스의 페이지들이 서로 연결됩니다.

SQL Server가 자동으로 지정하든 CHECKPOINT 문을 사용하여 수동으로 지정하든 상관없이 일단 지정된 검사점은 두 단계를 거칩니다. 1단계에서는 SQL Server가 플러시되어야 하는 모든 페이지에 표시를 합니다. 추적 플래그 3502를 실행하여 검사점 로깅이 활성화되면 SQL Server 오류 로그는 아래와 비슷한 정보를 얻습니다.

Ckpt dbid 6 started (4000) (검사점 시작) 
Ckpt dbid 6 phase 1 ended (0) (1단계 종료) 
Ckpt dbid 6 complete.(2단계 및 검사점 종료) 

2단계에서는 검사점 스레드가 표시된 모든 페이지를 플러시합니다. 이 단계는 플러시할 페이지 수, 디스크 하위 시스템의 속도, 서버의 포화 수준 및 기타 요인에 따라 1단계보다 훨씬 오래 걸립니다. 커밋되지 않은 모든 데이터 페이지가 데이터 캐시에서 디스크로 플러시되면 검사점이 완료됩니다.

검사점 프로세스 동안 단일 페이지 쓰기 횟수(개체: SQLServer, 카운터: I/O - Single Page Writes/sec)가 늘어날 수 있습니다. 이 카운터는 일반적으로 0입니다. 검사점 프로세스 동안, 새 트랜잭션이 검사점 스레드에 의해 아직 플러시되지 않은 데이터 페이지를 요청하면 SQL Server는 요청이 들어오는 대로 이들 페이지를 플러시합니다. 이는 정상적인 동작입니다.

SA가 SHUTDOWN 문을 실행할 때 각 데이터베이스에 대해 검사점이 지정됩니다. SQL Server가 시작될 때 그리고 각 데이터베이스가 복구된 후에도 검사점이 지정됩니다.

참고 trun. Log on chkpt. 데이터베이스 옵션을 설정하면 시스템 검사점 프로세스가 활성화될 때마다 로그가 잘립니다.

지연 기록기 프로세스

SQL Server는 지연 기록기라는 시스템 프로세스를 지원하며 sp_who를 실행하면 이를 볼 수 있습니다. 이 프로세스는 사용 가능한 버퍼 수가 free buffers 구성 옵션으로 설정한 임계값보다 적을 때 버퍼 플러시를 자동으로 시작합니다.

지연 기록기 프로세스가 있기 때문에 사용 가능한 버퍼를 만들기 위해 검사점을 자주 지정하지 않아도 됩니다. 지연 기록기가 사용하는 일괄 I/O 크기를 max lazywrite IO 구성 옵션을 사용하여 설정할 수 있습니다.

커밋되지 않은 데이터 페이지 플러시

SQL Server는 아래와 같은 상황일 때 캐시에서 디스크로 페이지를 플러시합니다.

  • 검사점이 지정되었을 때
  • 캐시로 새 페이지를 가져와야 할 때
  • 현재 캐시에 없는 페이지가 필요하지만 사용 가능한 버퍼 목록에 버퍼가 없다는 것이 확인되면 SQL Server는 캐시 페이지 체인에서 사용 가능한 버퍼를 찾습니다. 체인 검색이 끝나면 가장 오래된 버퍼의 페이지가 디스크로 플러시됩니다.

    사용 가능한 미사용 버퍼가 없고 사용 가능한 버퍼 목록에도 버퍼가 없는 경우, 페이지를 사용할 수 있을 때까지 페이지 요청 프로세스가 일시적으로 중단됩니다.

  • SELECT INTO가 끝나거나 bcp의 경우 각 배치가 끝날 때
  • 빠른 bcp(로그되지 않는 버전)를 사용할 때 또는 SELECT INTO를 사용하여 테이블을 만들 때 새로 삽입된 행은 로그에 기록되지 않습니다. 또한 이들 대부분 또는 모두가 여전히 캐시에 있을 수 있습니다. SQL Server가 검사점 없이 중단되는 경우에 데이터 손실을 최대한 막기 위해, 커밋되지 않은 모든 데이터 페이지는 bcp 배치 또는 SELECT INTO가 끝날 때 디스크로 플러시됩니다.

  • 트랜잭션이 완료될 때 로그 페이지가 플러시됩니다.
  • 트랜잭션이 커밋되거나 중단되면 로그 페이지가 디스크로 플러시됩니다.

  • 페이지가 분할될 때
  • 페이지가 분할되면 새로 할당된 페이지가 즉시 디스크로 플러시됩니다.

  • LOAD DATABASE가 실행될 때
  • LOAD DATABASE 문을 사용하여 데이터베이스가 복원될 때 덤프의 모든 페이지가 디스크에 직접 쓰입니다. 또한 백업의 일부가 아닌 데이터베이스의 모든 페이지도 초기화되어 디스크로 플러시됩니다. 예를 들어, 4MB 데이터베이스에서 10MB 데이터베이스로 백업을 로드하는 경우 나머지 6MB의 페이지가 모두 초기화되어 디스크에 쓰입니다.

  • 지연 기록기 프로세스가 실행될 때
  • 지연 기록기 프로세스는 사용 가능한 버퍼 수가 특정 임계값보다 적으면 버퍼 플러시를 자동으로 시작합니다. 플러시에 사용할 수 있는 버퍼가 없으면 지연 기록기는 오류 로그에 메시지를 씁니다.

비동기 I/O

특정 디스크 하위 시스템에서의 성능 수준

지금 소개하는 세 종류의 디스크 하위 시스템을 통해 디스크 하위 시스템 종류마다 비동기 I/O의 성능 효과가 얼마나 달라지는지 확인할 수 있습니다. 맨 먼저 4개의 디스크 드라이브에 장착된 비인텔리전트 컨트롤러를 소개합니다. 그 다음은 각각 단일 디스크 드라이브에 장착된 4개의 비인텔리전트 컨트롤러입니다. 마지막으로 4개의 디스크 드라이브에 장착된 단일 인텔리전트 컨트롤러를 소개합니다.

4개의 드라이브에 장착된 단일 컨트롤러

먼저, 단일 컨트롤러와 4개의 드라이브를 사용할 때 데이터 전송이 어떻게 이루어지는지 살펴보겠습니다. 아웃바운드 전송 시퀀스에서, 장치 드라이버는 컨트롤러의 내장 버퍼로 데이터 버퍼를 보냅니다. 이 동작은 일반적으로 직접 메모리 액세스(DMA), 공유 메모리 또는 프로그램된 I/O를 사용하여 아주 빠르게(일반적인 버스 속도에서 몇 백 밀리초 이내) 이루어집니다. 그런 다음 컨트롤러는 장치 드라이버로부터 여러 가지 지원을 받아 드라이브에서 필요한 찾기 동작을 수행해야 합니다. 이 동작에는 최대 50밀리초가 걸릴 수 있으며 이는 버스와 컨트롤러 간의 전송보다 수백 배나 긴 시간입니다.

이제 드라이브 종류에 따라 결정되는 전송 속도를 사용하여 컨트롤러 버퍼에서 디스크 드라이브로 실제 데이터가 전송됩니다. 전송이 시작되기 전에 회전 대기 시간도 있을 수 있습니다. 상당수의 시스템에서, 이 대기 시간 동안 장치 드라이버 및 장치 드라이버를 호출한 작업은 하드 디스크 드라이브가 완료되기만 기다려야 합니다. 첫째 드라이브가 완료될 때까지는 둘째 드라이브와 그 다음 드라이브에서 작업을 수행할 수 없습니다. 이는 대기 중인 여러 작업을 추적하는 데 필요한 논리를 컨트롤러가 가지고 있지 않기 때문입니다.

개별 드라이브에 장착된 4개의 컨트롤러

각각 자체의 드라이브에 장착된 4개의 컨트롤러를 사용하는 경우, Windows NT 스트라이프를 사용하면 둘째 또는 그 다음의 컨트롤러나 드라이브에서 전송 시퀀스가 즉시 시작될 수 있습니다. 이 경우 4개의 드라이브가 각각 자체의 컨트롤러를 사용하여 전송을 추적하기 때문에 이 드라이브들의 전송 단계가 서로 다를 수 있습니다.

이 하드웨어 구성에 Windows NT 비동기 I/O를 사용하면 도움이 될 수 있습니다. 처리되지 않은 I/O 풀을 만들 수 있고 드라이브 하위 시스템이 이 풀을 한 번에 4개씩 병렬로 처리할 수 있기 때문입니다. 드라이브 하위 시스템의 요청 처리 속도가 다를 수 있기 때문에, 하위 시스템의 용량이 최대한 사용되도록 처리되지 않은 SQL Server 요청 풀을 만드는 것이 좋습니다. 시스템 고유의 여러 가지 요소에 따라, 다수의 비동기 I/O를 허용하도록 SQL Server를 다시 구성하는 것이 유용할 수도 있습니다. 그러나 대다수 시스템의 확장 용량 때문에 드라이브마다 하나의 컨트롤러를 사용하기가 힘듭니다.

4개의 디스크 드라이브에 장착된 단일 인텔리전트 컨트롤러

기술이 발전함에 따라 이제 여러 비인텔리전트 컨트롤러의 기능을 단일 인텔리전트 컨트롤러에 효과적으로 포함할 수 있게 되었습니다. 컨트롤러는 장치 드라이버로부터 많은 I/O 요청을 빠르게 받아들인 다음 보통 RAID 어레이로 스트라이프되는 장착 드라이브에 요청을 효과적으로 동시 전송할 수 있습니다. 이 경우 컨트롤러의 기능과 구성에 따라, 많은 비동기 I/O를 허용하도록 SQL Server를 다시 구성하면 성능이 향상될 수 있습니다. 서버와 컨트롤러에 따라, 특정 서버나 컨트롤러에서는 디스크 하위 시스템 구성에 따라 그리고 특정 디스크 하위 시스템 구성에서는 응용 프로그램의 I/O 특성에 따라 실제로 사용되는 값은 달라집니다.

max async IO 구성

max async IO 구성 옵션은 요청할 수 있는 비동기 I/O 수를 설정합니다. 기본값은 8입니다. 서로 다른 실제 디스크에 존재하는 복수의 실제 데이터베이스 장치에 정의된 데이터베이스를 가진 시스템 또는 디스크 스트라이프를 사용하는 시스템에서만 이 기본값을 변경해야 합니다.

max async IO 구성 옵션의 최적 값은 Microsoft TPC-B Benchmark Kit를 사용하거나, 기본 설정 8로 시작해서 이어지는 테스트마다 값을 조금씩 늘리는 방식으로 자체적인 고객 벤치마크를 실시함으로써 특정 상황에 대한 제어된 테스트를 수행하여 결정하는 것이 좋습니다. 더 이상 성능 향상이 보이지 않으면 그 값이 최적 값입니다. 실제적인 테스트를 수행하지 않을 때는 기본값을 그대로 사용해야 합니다.

구성 옵션을 변경하면 SQL Server를 다시 시작해야 변경 사항이 적용됩니다.

max lazywrite IO 구성

max lazywrite IO 구성 옵션은 지연 기록기가 수행하는 비동기 일괄 처리 I/O의 우선 순위를 조정합니다. max lazywrite IO는 대량 복사, 검사점 같은 일괄 I/O를 제어하는 max async IO와 비슷하지만 지연 기록기 고유의 옵션입니다. 이 옵션은 하드 디스크가 여러 개 있는 시스템에서만 구성해야 합니다. max async IO에서 지정한 값까지 동적으로 이 옵션을 구성할 수 있습니다.

이 구성 옵션을 변경하면 변경 사항이 즉시 적용됩니다.

버퍼 관리자 구성

Free Buffers

이 구성 옵션은 시스템이 사용할 수 있는 사용 가능한 버퍼의 임계값을 결정합니다. 최소값은 20이며 최대값은 서버가 시작될 때 사용할 수 있는 버퍼 수의 절반입니다. 지연 기록기 프로세스는 시스템이 사용할 수 있는 사용 가능한 버퍼 수가 이 임계값 아래로 내려가지 않도록 합니다.

이 옵션은 memory 옵션이 변경될 때마다 시스템에 의해 자동으로 변경됩니다. free buffers는 사용 가능한 메모리의 5%로 설정됩니다. memory 옵션이 변경되면 free buffers가 변경되었다는 메시지가 나타납니다. 그러면 free buffers를 유효한 값으로 직접 재구성할 수 있습니다.

Sort Pages

이 구성 옵션은 정렬에 할당되는 사용자 당 최대 페이지 수를 지정합니다. 대량 정렬을 수행하는 시스템에서 이 값을 늘리면 성능이 향상될 수 있습니다. 추가 정렬 페이지는 메모리를 소모하기 때문에 이 값을 늘리면 서버 전용 메모리의 양도 늘려야 할 수 있습니다.

Hash Buckets

이 구성 옵션은 페이지를 메모리의 버퍼에 해시하는 데 사용되는 버킷 수를 설정합니다. 지정된 값이 최적 값이 아닌 경우 최적 값에 가장 가까운 값이 사용됩니다. 예를 들어, 8,000을 지정하면 7,993개의 해시 버킷(기본값)이 만들어집니다. 대량의 메모리가 있는 시스템에서는 데이터 캐시의 데이터에 더욱 빠르게 액세스하기 위해 이 값을 늘릴 수 있습니다. 메모리가 160MB 이하인 시스템에서는 7,993이 적당한 값입니다. 이 옵션은 서버를 종료한 후 다시 시작해야 적용됩니다.

Recovery Interval

이 구성 옵션은 시스템 장애 발생 시 SQL Server가 복구 절차를 완료하는 데 필요한 데이터베이스 당 최대 시간(분)을 설정합니다. 기본값은 5분입니다.

응용 프로그램 및 응용 프로그램 사용 상태가 바뀌면 recovery interval을 변경할 수 있습니다. 예를 들어, 업데이트 동작이 많을 때 변경 사항이 디스크에 자주 쓰이도록 하려면recovery interval을 줄일 수 있습니다. recovery interval을 줄이면 검사점이 더 자주 지정되기 때문에 시스템 속도가 약간 느려집니다. 그러나 recovery interval을 너무 높게 설정하면 복구 시간이 지나치게 길어질 수 있습니다.

페이지를 캐시에 유지

부분 구문

sp_tableoption @TableNamePattern [,'pintable'] [,true | false ]

pintable 옵션을 true로 설정하면 SQL Server가 테이블과 그 모든 인덱스를 데이터 캐시에 유지합니다. 고정된 테이블에 속하는 페이지들은 새 페이지를 위한 공간 확보를 위해 데이터 캐시 밖으로 플러시되지 않습니다. 고정된 테이블에 대한 모든 수정 사항은 로그에 기록되며 지연 기록기와 검사점은 고정된 모든 테이블의 커밋되지 않은 데이터 페이지를 일반적인 방식대로 씁니다.

sysobjects 테이블에 상태 비트를 설정하여 테이블을 고정된 테이블로 표시할 수 있습니다.

이 저장 프로시저는 테이블과 인덱스를 자동으로 메모리로 가져오지 않습니다. 즉, 데이터 및 인덱스 페이지는 액세스될 때 데이터 캐시로 들어온 다음 SQL Server가 중지되거나pintable의 값이 false로 설정될 때까지 계속 데이터 캐시에 남아 있습니다. 고정된 테이블을 메모리로 빠르게 가져오려면, 클러스터되지 않은 인덱스가 없는 열을 사용하여 SELECT COUNT(열_이름) FROM 테이블_이름 같은 간단한 명령으로 액세스하면 됩니다.

자주 사용되는 특정 테이블을 고정하면 특정 환경에서 성능을 크게 향상시킬 수 있습니다. 언제나 테이블을 고정한 후에도 데이터 캐시의 양이 충분히 남아 있도록 해야 합니다.

와일드카드를 사용하여 테이블 이름을 지정할 수 있습니다. 이렇게 하면 여러 테이블을 고정하거나 해제할 수 있습니다. true 또는 false 값을 지정하지 않으면 이 명령은 지정된 테이블의 현재 pintable 설정 값을 반환합니다.

참고 테이블 크기에는 제한이 없지만 테이블이 크면 캐시가 소모될 수 있습니다.

인덱스 페이지를 캐시에 유지

추적 플래그 1081은 인덱스 페이지가 데이터 캐시에 유지될 수 있도록 합니다. 새 페이지를 가져오기 위해 어떤 인덱스 페이지를 캐시 밖으로 플러시해야 하는 경우, SQL Server는 다른 페이지를 선택합니다. 단, 이 특정 인덱스 페이지를 건너뛴 적이 없어야 합니다. 따라서 인덱스 페이지가 데이터 캐시에 더 오래 유지될 수 있습니다.

미리 읽기 처리

미리 읽기를 병렬 데이터 스캔(PDS)이라고도 합니다. SQL Server는 이 방법을 사용하여 쿼리를 처리하는 데 필요한 물리적 읽기 횟수를 줄입니다. 특정 개수의 필요한 페이지가 캐시에 없으면, SQL Server는 현재의 SQL Server 프로세스에 필요한 페이지를 읽을 다른 스레드를 시작할 수 있습니다.

SQL Server가 데이터 수평 스캔을 수행할 때마다 미리 읽기가 시작될 수 있습니다. 수평 스캔에는 테이블 스캔, 클러스터되지 않은 인덱스에 대한 잎 수준 인덱스 스캔, DBCC 문 및 UPDATE STATISTICS가 포함될 수 있습니다.

미리 읽기 구성

RA Cache Miss Limit

SQL Server가 수평 데이터 스캔을 수행하는 동안 이 페이지 개수가 데이터 캐시에서 발견되지 않으면 미리 읽기가 시작됩니다. RA cache miss limit을 1로 설정하면 디스크에서 데이터 페이지가 액세스될 때마다 미리 읽기 요청이 이루어지며 이로 인해 스래싱이 발생하고 성능이 떨어질 수 있습니다.

RA Pre-fetches

이 값은 미리 읽기(RA) 관리자가 얼마나 멀리까지 미리 읽어야(확장 영역 단위로) 미리 반입 관리자가 유휴 상태가 되는지 결정합니다. 값이 3이면, 제출된 각 요청에 대해 RA 관리자가 페이지 체인에서 현재 스캔 위치보다 확장 영역 3개를 앞서갑니다.

RA Cache Hit Limit

이 개수의 필요한 페이지가 캐시에서 발견되면 미리 읽기가 중지되었다가 그 후에 처음으로 손실이 발견되면 다시 시작됩니다. 이 옵션은 미리 읽기 관리자가 캐시에서 모든 것을 발견하는 상황을 알아내는 데 사용되며 쿼리에는 거의 도움이 되지 않습니다. 대부분의 시스템에서는 기본값 4로 충분합니다.

RA Worker Threads

각 스레드는 구성 가능한 구조 수를 관리합니다(RA slots per thread 옵션 참조). 여기서 이러한 각 구조(슬롯)는 개별적인 범위 스캔을 나타냅니다. 이 옵션은 시스템에 대한 최대 동시 사용자 수로 설정해야 합니다. 미리 읽기 스캔을 요청하는 스레드 수가 구성된 RA 슬롯 수를 초과하면 오류 로그에 경고가 기록됩니다. 이 값을 0으로 설정하면 미리 읽기가 사용 해제됩니다.

RA Slots Per Thread

이 값은 각각의 미리 읽기 서비스 스레드가 관리할 동시 요청 수를 지정합니다. 스레드 수에 슬롯 수를 곱하면 시스템이 지원할 동시 미리 읽기 스캔의 총 개수가 됩니다. 대부분의 시스템에서는 기본값이면 충분합니다. 시스템에 효율적인 I/O 하위 시스템이 갖춰져 있으면 단일 스레드가 처리할 수 있는 스캔 수를 늘릴 수 있습니다.

RA Delay

쿼리 스레드가 미리 읽기를 호출할 때 그 시간과 운영 체제가 미리 읽기 스레드를 활성화하는 시간 사이에 약간의 지연이 있을 수 있습니다. 이 지연 옵션은 쿼리 스레드가 얼마 동안 대기해야 작업을 다시 시작할 수 있는지 설정합니다. 이는 미리 읽기 스레드가 시작된 다음 쿼리 스레드 작업이 계속되도록 하기 위해서입니다. 이 값을 0으로 설정하면 기본적으로 미리 읽기가 비활성화됩니다. 쿼리 스레드가 항상 미리 읽기가 활성화되기 전에 다음 페이지에 액세스하기 때문입니다.

미리 읽기 검토 및 제어

DBCC SQLPERF(RASTATS)는 4가지 통계를 반환합니다. 아래 출력 예제를 참조하십시오.

Statistic Value 
-------------------------------- ------------------------ 
RA Pages Found in Cache 297.0 
RA Pages Placed in Cache 12933.0 
RA Physical IO 1644.0 
Used Slots 0.0 

아래 표는 반환된 4가지 값의 의미를 정리한 것입니다.

통계 
정의 
RA Pages Found in Cache
스캔을 수행하려 할 때 RA 관리자가 캐시에서 발견한 페이지 수 
RA Pages Placed in Cache
RA 관리자가 캐시로 가져온 페이지 수 
RA Physical IO
RA 관리자가 수행한 16K 읽기 횟수 
Used Slots
활성 쿼리에 의해 사용되는 RA 슬롯 수. 단일 쿼리가 여러 개의 RA 슬롯을 사용할 수도 있습니다. 

SQL Server 프로시저 캐시

프로시저 캐시 구성

프로시저 캐시에는 아래 요소들이 포함됩니다.

  • 프로시저 버퍼 배열
  • 캐시 페이지 수만큼의 프로시저 버퍼 슬롯이 고정 배열로 저장됩니다. 각 프로시저 버퍼 슬롯은 122바이트의 프로시저 캐시를 사용합니다. DBCC MEMUSAGE 출력에서 프로시저 버퍼 배열을 유지하는 데 필요한 공간을 프로시저 헤더라고 합니다.

  • 프로시저 헤더
  • 사용된 각 프로시저 버퍼 슬롯은 프로시저 헤더를 가리킵니다. 이 헤더는 캐시에서 프로시저 계획 또는 트리의 첫째 페이지입니다. 이 첫째 페이지에는 계획이나 트리에 있는 다른 페이지의 주소 같은 메모리 관리 정보가 포함됩니다. 또한 호출 프로시저(있는 경우)는 물론 계획의 첫째 문에 대한 포인터도 포함됩니다. 이 구조는 처음 2K 페이지의 606바이트를 사용합니다. 2K 페이지의 나머지 바이트는 계획 또는 트리에 사용할 수 있습니다. 계획이나 트리의 크기에 따라 이들과 관련된 많은 추가 페이지가 있을 수 있습니다. DBCC MEMUSAGE 출력에서 프로시저 캐시로 사용될 사용 가능한 공간을 프로시저 캐시 버퍼라고 합니다.

  • 사용된 페이지에는 쿼리 계획 또는 쿼리 트리가 포함됩니다.
  • 활성 페이지에는 현재 실행되는 프로시저의 계획이 포함됩니다.
  • 빈 페이지는 새 계획에 사용할 수 있습니다.

같은 프로시저에 여러 계획이 있으면 이들 각자가 자체의 프로시저 버퍼 슬롯과 프로시저 헤더를 가집니다.

프로시저 캐시 크기 조정

프로시저 캐시 구성 옵션

procedure cache 값은 새 저장 프로시저를 만들고 새 쿼리를 컴파일하기 위해 SQL Server가 가장 최근에 사용된 저장 프로시저를 저장하는 데 사용할 메모리 양을 지정합니다.

지정된 값에 따라 SQL Server 메모리 요구 사항이 충족된 후 프로시저 캐시에 할당되는 메모리 백분율이 결정됩니다. SQL Server에 필요한 메모리는 잠금, 사용자 연결, 코드 자체 등에 필요한 메모리를 합한 양입니다. 나머지 메모리는 이 구성 옵션에 의해 설정된 백분율에 따라 프로시저 캐시와 데이터 캐시 간에 분할됩니다.

저장 프로시저, 트리거, 뷰, 규칙, 기본값 등에 필요한 프로시저 캐시의 양은 이들의 개수와 크기에 따라 달라집니다. 같은 저장 프로시저에 여러 사용자가 액세스하는 경우 캐시에 미사용 복사본이 없으면 SQL Server가 프로시저 계획의 복사본을 또 하나 만들어야 합니다.

이 매개 변수를 변경하면 SQL Server를 다시 시작해야 변경 사항이 적용됩니다.

프로시저 캐시 사용 모니터링

DBCC MEMUSAGE를 사용하여 프로시저 캐시에 있는 가장 큰 20개의 프로시저를 모니터할 수 있습니다.

DBCC MEMUSAGE의 출력 내용은 프로시저 캐시에 필요한 공간을 예측하는 데 도움이 될 수 있습니다. 이 출력에 캐시에 있는 계획의 크기가 제공되므로 이 수를 예상되는 동시 사용자 수와 곱할 수 있습니다.

프로시저 캐시는 아래의 두 방식 중 하나로 구성될 수 있습니다.

  • 사용할 수 있는 사용 가능한 페이지가 많이 있거나 덮어쓸 수 있는 비활성 상태의 사용된 페이지가 있더라도, 다수의 작은 프로시저가 프로시저 버퍼 배열을 채울 수 있습니다.
  • 프로시저 버퍼 배열에 사용 가능한 슬롯이 있더라도 몇 개의 큰 프로시저가 사용 가능한 모든 페이지를 사용할 수 있습니다.

프로시저 캐시가 가득 차서 새 프로시저를 실행할 수 없는 경우 아래와 같은 오류 701이 반환됩니다.

There is insufficient system memory to run this query. 

성능 모니터 카운터

개체: SQLServer – Procedure Cache 
카운터: Procedure Cache Size 및 Procedure Cache Used %

Procedure Cache Size 카운터는 2K 페이지의 프로시저 캐시 크기를 보고합니다. memory 또는 procedure cache 구성 옵션 값을 변경한 다음 SQL Server를 다시 시작하지 않는 한 이 카운터는 변경되지 않습니다.

Procedure Cache Used % 카운터는 캐시된 저장 프로시저, 트리거, 뷰, 규칙 및 기본값이 사용하는 프로시저 캐시의 백분율을 모니터합니다.

장기적인 관점에서 Procedure Cache Used % 카운터를 90-95% 정도로 만드는 것이 이상적입니다.

Procedure Cache Used % 카운터가 이보다 훨씬 낮은 경우 프로시저 캐시에 메모리를 너무 많이 할당한 것이며 데이터 캐시에 사용할 수 있는 메모리를 낭비하고 있는 것입니다. 따라서 프로시저 캐시 값을 낮추고 SQL Server를 다시 시작한 다음 이 카운터를 계속 모니터해야 합니다.

Procedure Cache Used % 카운터가 지속적으로 95% 이상인 경우 프로시저 캐시를 충분히 할당하지 않은 것입니다. 이런 경우 프로시저 캐시 구성 옵션의 값을 늘리고 SQL Server를 다시 시작한 다음 모니터링 프로세스를 계속해야 합니다.

기타 SQL Server 구성 옵션

Max Worker Threads

이 구성 옵션은 SQL Server 프로세스에 사용할 수 있는 작업자 스레드 수를 구성합니다. SQL Server는 운영 체제 고유의 스레드 서비스를 사용합니다. 작업자 스레드는 하나가 아니라 여러 개 있습니다. SQL Server가 동시에 지원하는 각 네트워크는 하나 이상의 스레드에 의해 지원됩니다. 또 다른 스레드는 데이터베이스 검사점을 처리하며 스레드 풀은 모든 사용자를 처리합니다.

max worker threads 옵션을 사용하면 사용자 풀에 할당되는 스레드 수를 제어할 수 있습니다. 사용자 연결 수가 max worker threads보다 적으면 한 스레드가 각 연결을 처리합니다. 그러나 연결 수가 max worker threads보다 많으면 스레드 풀링이 이루어집니다. 또한 설정된 작업자 스레드 값이 초과되면 현재 작업을 완료하는 그 다음 작업자 스레드가 그 요청을 처리합니다. 기본값은 255입니다.

Logwrite Sleep

이 구성 옵션은 버퍼가 가득 차지 않은 경우 로그에 대한 쓰기를 얼마 동안(밀리초) 지연시킬 것인지 지정합니다. 이 옵션을 사용하면, 다른 사용자가 더 많은 데이터를 로그 버퍼에 추가할 기회가 많아지기 때문에 필요한 물리적 로그 쓰기가 줄어듭니다. 이 옵션에 허용되는 값은 1에서 500까지입니다. 특별한 값인 -1을 사용하면 로그 쓰기가 지연되지 않습니다. 기본값은 0이며 이 값을 사용하면 다른 사용자가 실행할 준비가 되었을 때만 서버가 대기합니다.

이 매개 변수에 대한 변경 사항은 즉시 적용됩니다.

Priority Boost

이 구성 옵션은 SQL Server가 동일 컴퓨터의 다른 프로세스보다 높은 순위로 실행되도록 할 것인지 여부를 결정합니다. 이 옵션을 1로 설정하면 SQL Server가 더 높은 우선 순위로 실행됩니다. 기본값은 0이며 SQL Server 전용 Windows NT 시스템에서만 변경해야 합니다. 네트워크 등 필요한 다른 프로세스가 중단되지 않도록 주의해야 합니다.

SMP Concurrency

이 구성 옵션은 SQL Server가 실행을 위해 Windows NT에 보낼 스레드 수를 제어합니다. 이는 사실상 SQL Server가 사용하는 CPU 수를 제한합니다. 단일 프로세서 컴퓨터인 경우 최적 값은 1입니다. 대칭 다중 프로세서(SMP) 컴퓨터인 경우 서버가 전용 SQL Server인지 여부에 따라 제한이 달라집니다. 전용 서버가 아닌 경우 이 값을 다시 구성하면 동일 시스템에서 실행되는 다른 응용 프로그램에 대한 응답 시간이 느려질 수 있습니다. 다른 응용 프로그램에 대한 응답 시간이 문제가 되지 않는 경우에는 SMP concurrency -1, 즉 "전용 SMP 지원"으로 설정하십시오. 이는 어떤 제한도 없다는 뜻입니다.

SQL Server를 설치하면 SMP concurrency가 0으로 설정됩니다. 이는 자동 구성을 뜻합니다. 자동 구성 모드에서는 n-1로 설정됩니다. 여기서 n은 SQL Server를 시작할 때 검색되는 프로세서 수입니다. 단일 프로세서 시스템에서는 이 값이 1로 설정됩니다.

이 매개 변수를 변경하면 SQL Server를 다시 시작해야 변경 사항이 적용됩니다.

Set Working Set Size

이 구성 옵션은 Windows NT가 memory 설정과 tempdb 크기의 합계에 해당하는 실제 메모리 공간(RAM에 있는 경우)을 SQL Server를 위해 예약하도록 합니다.

Network Packet Size

이 구성 옵션은 기본 네트워크 패킷 크기에 대해 서버 차원의 값을 설정합니다. 클라이언트 응용 프로그램은 이 값을 무시할 수 있습니다. 여러 네트워크 프로토콜을 사용하는 시스템에서는 이 옵션을 가장 일반적으로 사용되는 프로토콜의 크기로 설정해야 합니다. 네트워크 프로토콜이 큰 패킷을 지원하는 경우 이 옵션으로 네트워크 성능을 향상시킬 수 있습니다. 옵션을 재구성하면 변경 사항이 즉시 적용됩니다. 기본값은 4,096입니다.

이 매개 변수에 대한 변경 사항은 즉시 적용됩니다.

데이터베이스 및 세션 구성

데이터베이스 옵션

데이터베이스 옵션은 데이터베이스 소유자 또는 SA만 변경할 수 있습니다. 데이터베이스 옵션은 마스터 데이터베이스에 저장되기 때문에 데이터베이스 소유자를 가장한 누군가가 이를 변경할 수 없습니다.

아래 데이터베이스 옵션들이 쿼리 성능에 영향을 미칠 수 있습니다.

read only 
single user only

두 경우 모두, 어떠한 동작에 대해서도 잠금이 이루어지거나 확인되지 않습니다. 해당 문서에서 설명하겠지만 다중 사용자 환경에서는 잠금 경합이 가장 중대한 성능 문제 중 하나입니다.

다른 데이터베이스 옵션들은 더 간접적인 방식으로 성능에 영향을 미칠 수 있습니다. trunc. log on chkpt 옵션은 시스템 검사점 프로세스가 실행될 때마다 추가적인 시스템 오버헤드를 유발합니다. select into/bulkcopy 옵션을 사용하면 빠른 대량 복사 또는 SELECT INTO 작업을 수행할 수 있습니다. 이들은 다른 방법들보다 훨씬 빠릅니다.

테이블 옵션

테이블 옵션도 성능에 영향을 미칠 수 있습니다. 테이블 옵션은 sp_tableoption을 사용하여 설정합니다. pintable 테이블 옵션에 대해서는 앞에서 이미 설명했습니다. insert row lock 테이블 옵션에 대해서는 해당 문서에서 설명합니다.

세션 옵션

세션 옵션은 SET 명령으로 제어하며 세션이 유지되는 동안에만 효력을 나타냅니다. 저장 프로시저에서 세션 옵션을 사용 설정하면 그 저장 프로시저가 종료될 때까지 이들의 효력이 유지됩니다.

아래 세션 옵션들이 쿼리 성능에 영향을 미칠 수 있습니다.

FORCEPLAN

SQL Server 최적화 프로그램 프로세스가 FROM 절에 나타나는 테이블 순서대로 조인하도록 합니다. FORCEPLAN은 기본적으로 최적화 프로그램을 무시합니다.

DEADLOCKPRIORITY {LOW | NORMAL}

교착 상태가 발생할 때 이 세션이 응답할 방식을 제어합니다. LOW로 설정하면 이 프로세스가 교착 상태에서 우선적으로 희생됩니다. NORMAL 옵션을 사용하면 세션을 기본 교착 상태 처리 방법으로 되돌릴 수 있습니다.

TRANSACTION ISOLATION LEVEL

이 연결에 대해 모든 SQL Server SELECT 문의 기본 트랜잭션 잠금 동작을 제어합니다. 해당 문서에서 다양한 값에 대해 설명합니다.

IMPLICIT_TRANSACTIONS

문이 실행될 때 트랜잭션이 묵시적으로 시작되도록 할 것인지 여부를 제어합니다. 이 동작이 성능에 미치는 영향에 대해서는 해당 문서에서 설명합니다.

DISABLE_DEF_CNST_CHK

임시로 지연된 위반 검사를 지정합니다. 이 옵션의 의미 및 성능 영향에 대해서는 해당 문서에서 설명합니다.

© 1997 Microsoft Corporation. All rights reserved.

이 문서에 포함된 정보는 문서를 발행할 때 논의된 문제들에 대한 Microsoft Corporation의 당시 관점을 나타냅니다. Microsoft는 변화하는 시장 환경에 대처해야 하므로 이를 Microsoft 측의 책임으로 해석해서는 안 되며 발행일 이후 소개된 어떠한 정보에 대해서도 Microsoft는 그 정확성을 보장하지 않습니다.

이 설명서는 오직 정보를 제공하기 위한 것입니다. Microsoft는 이 설명서에서 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.

Microsoft 및 Windows NT는 Microsoft Corporation의 등록 상표입니다.

여기에 인용된 다른 제품이나 회사 이름은 해당 소유자의 상표일 수 있습니다.


Posted by 디오디오
TAG db, mssql

Double, double, oil and trouble

May 29th 2008
From The Economist print edition

Is it “peak oil” or a speculative bubble? Neither, really

AFTER oil hit its recent record of $135 a barrel, consumers and politicians started to lash out in every direction. Fishermen in France have been blockading ports and pouring oil on the roads in protest. British lorry drivers have paraded coffins through London as a token of the imminent demise of the haulage industry. In response, Gordon Brown, Britain's prime minister, is badgering oil bosses to increase production from the North Sea, while Nicolas Sarkozy, the president of France, wants the European Union to suspend taxes on fuel.

In America, too, politicians are haranguing oil bosses and calling for tax cuts. Congress has approved a bill to prevent the government from adding to America's strategic stocks of oil, and is contemplating another to enable American prosecutors to sue the governments of the Organisation of the Petroleum Exporting Countries (OPEC) for market manipulation.

But the most popular scapegoats are “speculators” of the more traditional sort. OPEC itself routinely blames them for high prices. The government of India is so sure that speculation makes commodities dearer that it has banned the trading of futures contracts for some of them (although not oil). Germany's Social Democratic Party proposes an international ban on borrowing to buy oil futures, on the same grounds. Joe Lieberman, chairman of the Senate's Homeland Security Committee, is also mulling regulation of some sort, having concluded that “speculators are responsible for a big part of the commodity price increases”. The assumption underlying such ideas is that a bubble is forming, and that if it were popped, the price of oil would be much lower.

Others assume the reverse: that the price is bound to keep rising indefinitely, since supplies of oil are running short. The majority of the world's crude, according to believers in “peak oil”, has been discovered and is already being exploited. At any rate, the size of new fields is diminishing. So production will soon reach a pinnacle, if it has not done so already, and then quickly decline, no matter what governments do.

As different as these theories are, they share a conviction that something has gone badly wrong with the market for oil. High prices are seen as proof of some sort of breakdown. Yet the evidence suggests that, to the contrary, the rising price is beginning to curb demand and increase supply, just as the textbooks say it should.

Stocks, bonds and barrels

Those who see speculators as the culprits point to the emergence of oil and other commodities as a popular asset class, alongside stocks, bonds and property. Ever more investors are piling into the oil markets, the argument runs, pushing up the price as they do so. The number of transactions involving oil futures on the New York Mercantile Exchange (NYMEX), the biggest market for oil, has almost tripled since 2004. That neatly mirrors a tripling of the price of oil over the same period.

But Jeffrey Harris, the chief economist of the Commodity Futures Trading Commission (CFTC), which regulates NYMEX and other American commodities exchanges, does not see any evidence that the growth of speculation in oil has caused the price to rise. Rising prices, after all, might have been stimulating the growing investment, rather than the other way around. There is no clear correlation between increased speculation and higher prices in commodities markets in general. Despite a continuing flow of investment in nickel, for example, its price has fallen by half over the past year.

By the same token, the prices of several commodities that are not traded on any exchange, and are therefore much harder for speculators to invest in, have risen even faster than that of oil. Deutsche Bank calculates that cadmium, a rare metal, has appreciated twice as much as oil since 2001, for example, and the price of rice has risen fractionally more.

Investment can flood into the oil market without driving up prices because speculators are not buying any actual crude. Instead, they buy contracts for future delivery. When those contracts mature, they either settle them with a cash payment or sell them on to genuine consumers. Either way, no oil is hoarded or somehow kept off the market. The contracts are really a bet about which way the price will go and the number of bets does not affect the amount of oil available. As Mr Harris puts it, there is no limit to the number of “paper barrels” that can be bought and sold.

That makes it harder for a bubble to develop in oil than in the shares of internet firms, say, or in housing, where the supply of the asset is finite. Ultimately, says David Kirsch of PFC Energy, a consultancy, there is only one type of customer for crude: refineries. If speculators on the futures markets get carried away, pushing prices so high that refineries run at a loss, they will simply shut down, causing the price to fall again. Moreover, speculators do not always assume that prices will rise. As recently as last year, the speculative bears on NYMEX outweighed the bulls.

There is, admittedly, a growing category of inherently bullish investment funds that seek to track commodity-price indices, in which oil is usually the biggest component. Politicians have begun to denounce these “index funds”, since they make money for their investors only if prices rise. According to Mr Lieberman, they have grown in value from $13 billion to $260 billion over the past five years. This surge of investors betting on rising prices, many observers contend, has become a self-fulfilling prophecy, helping to push prices ever higher and thus attract yet more investment.

But Bob Greer, of PIMCO, an asset-management firm, argues that even index funds make unlikely suspects. For one thing, they too invest in futures, rather than in physical supplies of oil. So every month, they must trade contracts that are about to fall due for ones that will not mature for several months. That makes them big sellers of oil for prompt delivery.

What is more, their growth is not as impressive as it first appears. Paul Horsnell of Barclays Capital, an investment bank, puts the total value of index funds and other similar investments at $225 billion. That is less than half the market capitalisation of Exxon Mobil, he points out, and a tiny fraction of the $50 trillion-odd of transactions in the oil markets each year. Although index funds have grown quickly, that growth stems in large part from the rise in value of the futures they hold, rather than from fresh investment flows. He estimates that index funds swelled by $13 billion in the first quarter of this year, for example, of which all but $2 billion derives from the rise in commodity prices.

Back to basics

Mr Harris of the CFTC, for one, believes that the oil price is still a function of supply and demand. For the past few years, the world's production capacity has grown only sluggishly. Meanwhile, demand, especially from the developing world, has been growing faster. So there is hardly any slack in the system. Only Saudi Arabia and the United Arab Emirates are thought to be able to increase their output from today's levels, and even then, there are doubts, since Saudi Arabia, in particular, is secretive about the state of its oil industry.

That leaves the oil market at the mercy of even small disruptions to supply. Prices tend to jump each time militants sabotage an oil pipeline in Nigeria, bad weather threatens production in the Gulf of Mexico, or political clouds gather over the Persian Gulf.

The problem is exacerbated by a growing mismatch between the type of oil being produced and the refineries that must process it. The most common benchmark prices, including the one used in this article, refer to “light” crude, the least viscous sort, which produces the most petrol and diesel when refined. “Heavy” oil, by contrast, yields more fuel oil, which is used mainly for heating.

At the moment, diesel is in short supply and there is a glut of fuel oil. That makes processing heavy oil unprofitable for some refineries, since the gains from diesel are outweighed by losses on fuel oil. As refineries turn instead to lighter grades, it pushes their prices yet higher. The discount on heavier crudes has risen to record levels. But even then, points out Ed Morse, of Lehman Brothers, another investment bank, Iran is having trouble selling the stuff. It is storing huge quantities of unsold oil on tankers moored off its coast.

Presumably, Iran and other heavy-oil producers will eventually be obliged to drop prices far enough to make processing the stuff worth refiners' while. In the longer run, more refineries will invest in the equipment needed to crack more diesel out of heavy oil. Both steps will, in effect, increase the world's oil supply, and so help to ease prices.

But improving an existing refinery or building a new one is a slow and capital-intensive business. Firms tend to be very conservative in their investments, since refineries have decades-long life-spans, during which prices and profits can fluctuate wildly. It can also be difficult to find a site and obtain the right permits—one of the reasons why no new refineries have been built in America for over 30 years. Worse, new kit is becoming ever more expensive. Cambridge Energy Research Associates (CERA), a consultancy, calculates that capital costs for refineries and petrochemical plants have risen by 76% since 2000.

Much the same applies to the development of new oilfields. CERA reckons that the cost of developing them has risen even faster—by 110%. At the same time, oilmen remain scarred by the rapid expansion of output in the late 1970s, in response to previous spikes in prices, that led to a glut and so to a prolonged slump. Exxon Mobil claims that it still assesses the profitability of potential investments using the same assumptions about the long-term oil price as it did at the beginning of the decade, for fear that prices might tumble again. Environmental concerns are also an obstacle: America, for one, has banned oil production off most of its coastline.

Increasing nationalism on the part of oil-rich countries is adding to the difficulties. Geologists are convinced that there is still a lot of oil to be discovered in the Middle East and the former Soviet Union, but governments in both regions are reluctant to give outsiders access. Elsewhere, the most promising areas for exploration are also the most technically challenging: in deep water, or in the Arctic, or both. Although there have been big recent discoveries in such places, they will take longer to develop, and costs will be higher. The most expensive projects of all involve the extraction of oil from bitumen, shale and even coal, through elaborate processing. The potential for these is more or less unlimited, although analysts put the costs as high as $70 a barrel—more than the oil price this time last year.

Nonetheless, PFC Energy has examined projects that are already under way, and concluded that global oil production will grow by over 3m barrels a day (b/d) over the course of this year and next. In particular, it expects production outside OPEC to grow by about 500,000 b/d both years—a marked increase from the near stagnation of recent years.

Meanwhile, the high price is clearly beginning to crimp demand. The growth in global consumption last year was barely a quarter what it was in 2004 (see chart); this year, it is likely be even lower. In rich countries (or at least among the members of the Organisation for Economic Co-operation and Development (OECD), a rough proxy), the effect is even more pronounced. Consumption has been falling for the past two and a half years.

Poorer countries' demand for oil is still rising, albeit at a slowing pace. That is partly because their economies are growing faster, and partly because their consumers are shielded from the rising price through subsidies. But the increasing expense of such measures is forcing governments to water them down or scrap them altogether (see article). That, in turn, should further sap consumption.

Oil pique

China's growing thirst for oil is often put forward as one of the main factors behind today's higher oil prices. Demand for diesel there, for example, rose by over 9% in the year to April. But Mr Morse argues that such growth might not last. The government has ordered oil firms to increase their stocks of fuel by 50% to be sure there are no embarrassing shortages during the Olympics. It is also planning to run some power plants near Beijing on diesel rather than coal, in an attempt to reduce pollution during the games. These measures are helping to boost China's demand for diesel, but the effect will be transitory.

In the short run, neither demand for nor supply of oil is very elastic. It takes time for people to replace their old guzzlers with more fuel-efficient cars, or to switch to jobs with shorter commutes, or to move closer to public transport. By the same token, it can take ten years or more to develop an oilfield after its discovery—and that does not include the time firms need to bolster their exploration units.

Gary Becker, an economist at the University of Chicago, has calculated that in the past, over periods of less than five years, oil consumption in the OECD dropped by only 2-9% when the price doubled. Likewise, oil production in countries outside OPEC grew by only 4% every time the price doubled. But over longer periods, consumption dropped by 60% and supply rose by 35%. The precise numbers may be slightly different this time round, but the pattern will be the same.

Posted by 디오디오

Asia's other miracle

Apr 24th 2008
From The Economist print edition

Vietnam has developed at stunning speed by letting market forces do their work. It should free up its politics, too


NOT so long ago the word “Vietnamese” was almost inevitably accompanied in press reports by the phrase “boat people”. For two decades after the fall of Saigon in 1975, the defining image of Vietnam was the waves of bedraggled refugees washing up on its neighbours' shores, fleeing oppression and penury back home. How things have changed. Today, many former refugees are returning to seek new careers and start businesses in a transformed Vietnam. It is now one of Asia's fastest-developing countries, with annual growth averaging 7.5% over the past decade. Although this is less stellar than China's growth, our special report this week finds that Vietnam has made more impressive progress in cutting poverty than its vast northern neighbour. The government's initial hopes for 9% growth this year may be dashed, as the country struggles with double-digit inflation and a yawning trade gap. But the long-term outlook remains promising.

Shooting out of poverty

Vietnam's cities are bright and bustling and the countryside, where most of its 85m people still live, seems hardly less developed than that of officially much richer Thailand. A country once on the brink of famine has turned itself into one of the biggest exporters of farm produce. In a stark reversal of fortunes, the Philippines—once Asia's second-richest country—recently had to beg Vietnam to sell it rice for its hungry millions. Vietnam's social and economic progress has made it the poster-child of multilateral institutions such as the World Bank. It has become one of the fastest-growing destinations for multinational firms and holidaymakers. It is a rising diplomatic power: in July it will chair the UN Security Council, on which it holds a temporary seat.  

There are many useful things Vietnam could do with its new-found prestige, through both example and active diplomacy. Other countries in transition could benefit from its advice on how to set aside old enmities, open up to the world and reform defunct economies. As a rare friend of North Korea and Myanmar, Vietnam could help coax those benighted places out of self-imposed isolation. As a country that has escaped deep poverty by embracing free trade, Vietnam could encourage developing countries to take a more constructive stance in the Doha round of world trade talks (and shame richer ones into doing the same).

Remarkable as its achievements are, Vietnam is still not satisfied. It wants to go all the way to become a rich, high-tech country and has set a target date of 2020 for getting there. As several foes have learnt over the past century, the intelligence and determination of the Vietnamese should not be underestimated. But if it wants to realise its dream, Vietnam must learn the right lessons from its own story so far, and from those neighbours who have got to where it wants to be.

Vietnam began to be a success only after its ruling Communists accepted that capitalism, free markets and free trade were the surest route to riches. They began in 1986 with a liberalisation programme called doi moi (renewal), though real reform came in fits and starts over the following 20 years. Collectivisation was scrapped, farmers were given their own land to till and agricultural prices were freed. In 2000, private business—until then strictly curbed—was legalised and a stockmarket created. Trade barriers were lowered, exports and imports soared, and Vietnam is now among the world's most open economies. There can probably be no going back: any attempt to reapply the dead hand of government will ensure that Vietnam's dream of riches by 2020 remains just a dream.

Like South Korea, Taiwan and now China, Vietnam has shown it is possible to escape poverty under an authoritarian system. But it is surely no coincidence that most of the world's richest countries by income per head are liberal democracies. Political freedom is a right in itself and it does not need to be justified by arguing that it has economic advantages. But it does have them. Vietnam's leaders are already discovering that it is hard to run a thriving market economy with the methods that suited a planned economy. Managing all the strains of a fast-developing society is easier if there is a free market in opinions as well as in goods and services. In particular, tough but necessary economic decisions are easier to sell if citizens feel they have had some say in them.

Now become a star

So far, the Communist Party seems determined to retain its monopoly on power. It calls pro-democracy campaigners “terrorists” and puts them in jail. But it should take special note of the experience of South Korea and Taiwan. Until the late 1980s they too were dictatorships. Their regimes, facing rising dissent, saw the writing on the wall and democratised. Now, though their politics are a bit rough, they have the sort of prosperous, technology-based economies that Vietnam aspires to. The Vietnamese Communist Party seems instead to have been taking more interest in the example offered by Singapore, another prosperous, high-tech neighbour. Singapore's tiny size makes it a bit of an exception but even its constrained democracy—with rivals to the ever-ruling People's Action Party allowed to compete within tight constraints—would be a good start for Vietnam.

It is true that Vietnam also has neighbours, such as the Philippines and Thailand, where democracy has been a bumpy ride. But what this demonstrates is that democracy is a necessary rather than sufficient condition for reaching the premier league. The present generation of Vietnamese leaders, children of the independence struggle who want the best for their people, should think about who might come after them. If the next generation is less principled and more corrupt but cannot be dislodged from power, the country will slide backwards.

So far there are few signs of revolt against one-party rule. But as the Vietnamese get used to their broad economic and social freedoms, they are bound to appear eventually. Why wait? How much better for Ho Chi Minh's heirs to go down in history as having led the way in bringing stability, prosperity and, at last, real freedom to the people of Vietnam.

Posted by 디오디오
Posted by 디오디오
TAG 아고라

의료산업화, 참혹한 미래 불러올 것?


[kbs 미디어오늘 이정환 ] 우석균 성수의원 원장을 처음 인터뷰했을 때를 잊을 수 없다. 영화에나 나올 것 같은 허름한 병원도 낯설었지만 그는 도저히 의사처럼 보이지 않았다. 머리는 언제 감았는지 모르게 헝클어져 있었고 코털이 삐져나와 있었고 감기에 걸렸는지 계속 콜록거렸고 교통사고가 났다면서 팔에는 붕대까지 감고 있었다. 게다가 인터뷰 하는 동안 내내 담배를 피워댔다. 어딘가 당장 입원이라도 해야 할 것 같은 분위기였다.

그를 다시 만난 것은 이명박 정부가 밀어붙이고 있는 일련의 의료 산업화 정책에 대한 좀 더 구체적인 의견을 듣기 위해서였다. 보건의료단체연합 정책실장을 맡고 있는 그는 한미자유무역협정(FTA)와 관련, 미국산 소고기와 유전자변형식품(GMO) 수입 문제 등으로 정신 없이 바쁜 날을 보내고 있다. 올해 들어서는 이명박 정부의 의료 산업화 정책이 최대 현안으로 떠올랐다. 이명박 정부는 우리나라 의료 시스템을 송두리째 바꿔놓을 계획인데 정작 이에 대해 비판하는 사람은 많지 않다.

허름한 성수의원은 1988년 원진레이온 노동자들의 산재 투쟁을 이끌었던 양길승 녹색병원 원장이 설립한 곳이다. 성수의원은 이 지역 주민들에게 단순히 병원 이상의 공간이다. 양 원장의 뒤를 이어 받은 우 원장은 성동건강복지센터를 설립해 저소득 계층과 외국인 노동자들을 대상으로 무상 진료를 실시하고 있다. 간판조차 찾기 힘든 작은 병원이지만 환자들이 끊이지 않고 몰려드는 것도 이 병원과 우 원장에 대한 무한한 신뢰 때문이다.

인터뷰는 지난달 31일 오후, 우 원장이 환자를 보는 틈틈이 5시간에 걸쳐 이뤄졌다.
- 이명박 정부의 의료 산업화 정책은 크게 세 가지로 정리할 수 있을 것 같다. 영리병원을 허용하고 건강보험 당연지정제를 폐지하고 민영보험을 활성화하는 것, 그리고 하나 더하자면 장기적으로 건강보험 재정을 축소하는 것 등이다. 벌써부터 그 부작용을 지적하는 목소리가 많은데 도대체 모르고 밀어붙이는 것인가, 아니면 알면서도 밀어붙이는 것인가. 어떻게 생각하나. "이명박 정부가 추진하고 있는 의료산업화 정책은 2005년 삼성경제연구소에서 낸 '의료산업 고도화의 과제'라는 보고서에서 그대로 배껴온 것이다. 애초에 삼성생명과 삼성의료원으로 대변되는 국내 보험회사들과 대형 병원의 이해관계를 그대로 반영한 것이라는 이야기다. 이른바 '고소영'이나 '강부자'라는 사람들은 민영 의료보험에도 들고 비용을 더 부담하더라도 더 좋은 병원을 찾고 싶을 것이다. 건강보험을 축소하고 각자 알아서 해결하자고 주장하는 사람들도 바로 이 사람들이다. 건강보험 안 받는 병원을 만들자는 주장은 거대 자본과 일부 부유층의 이해가 맞물려 나온 발상이다."

- 이명박 정부는 태국이나 싱가포르와 비교도 한다. 의료 산업화를 통해 경쟁력을 높이면 해외로 빠져 나가는 의료비도 줄이고 오히려 해외 환자들도 받을 수 있지 않겠느냐는 논리인데.

"싱가포르는 공립 병원이 80%가 넘는다. 병상으로 치면 85% 정도다. 우리나라는 병원이 8% 정도, 병상 수로는 15% 정도다. 애초에 인프라가 다르다는 이야기다. 싱가포르는 교육과 의료와 주택을 나라에서 제공하고 그 위에 의료 산업화가 있다. 구체적으로 보면 가장 큰 레플즈 병원만 해도 외국 환자들이라고 해봐야 인도네시아나 말레이시아 등 이웃 나라의 해외 상사 직원들이 대부분이다. 생각해 봐라. 누가 자기 나라에 있는 좋은 병원 두고 말도 안 통하는 낯선 다른 나라에서 치료를 받겠는가. 싱가포르처럼 의료 수출이 성공하려면 조건은 세 가지다. 언어가 같고 이웃 나라의 의료 시스템이 부실하고 또 해외 나가서 치료를 받을만한 부유층이 있어야 한다. 그런데 우리나라를 봐라. 일본이나 중국과 언어도 다르고 일본은 감기만 걸려도 자기네 나라 돌아가 치료하는 사람들이다. 누가 우리나라 병원을 찾겠는가. 게다가 우리나라 물가가 일본이나 중국보다 싼가. 절대 그렇지 않다."

- 태국은 어떤가. 태국으로 성형수술 받으러 가는 사람들도 많고 그만큼 외화 획득에도 도움이 된다고 하지 않은가. "태국은 의사들이 모두 성형수술만 하는 바람에 의료 시스템이 엉망이다. 농촌은 의사들 찾아보기가 어렵다. 의료 시스템이 외국 환자 따로 국내 환자 따로 분리할 수 없기 때문에 태국 사람들 입장에서는 전반적으로 의료비가 터무니없이 높다. 아마 정부 관계자들은 수박 겉핥기식으로 구경만 하고 왔거나 아니면 알면서도 이런 현실을 무시하고 있을 가능성이 크다. 도대체 의료 산업으로 성장률을 올리겠다는 나라가 세계에 어디 있나."

- 민영 의료보험 활성화부터 이야기해보자. 우리나라는 이미 민영 의료보험이 꽤나 활성화된 상태다. 집집마다 암 보험 하나 안 든 곳이 없는데. 얼마나 더 활성화한다는 이야기인가. "가구로 보면 65~70% 정도가 암 보험 등 민영 의료보험에 가입해 있다. 생명보험은 90%가 넘는다. 이미 포화상태인 셈인데 이를 해결하기 위해 실손형 보험으로 가려는 것이다. 지금까지는 정액으로 암이면 얼마, 어디 부러지면 얼마, 입원하면 얼마 이렇게 나왔는데 이제는 병원비가 나오는대로 보장을 해주겠다는 것이다. 굳이 말하자면 민영 의료보험에 가입하는 대신 나홀로 무상 진료가 되는 셈인데 문제는 보험료가 턱없이 올라갈 수밖에 없다는 것이다. 지금 우리나라 의료비 가운데 건강보험 빼고 본인 부담이 10조원 정도인데 이게 모두 민영 의료보험 시장이 된다. 민영 의료보험으로 옮겨가는 과정에서 10조원 이상으로 늘어나게 될 가능성도 있다. 보험회사들 몫을 챙겨야 할 테니까."

- 건강보험공단이 보유하고 있는 개인 질병정보를 민영 의료보험과 공유해야 한다는 주장도 나오고 있다. 무슨 이유에서인가. "보험회사 입장에서는 실손형 보험의 경우 가입자가 병에 걸리면 진료비를 모두 부담해야 하기 때문에 병에 걸릴 확률이 높은 사람을 제외하려고 할 것이다. 건강한 사람만 받아야 수익을 높일 수 있기 때문이다. 미국에서는 생명보험과 의료보험 사이에도 정보 교환을 금지하고 있고 의료보험 사이에서도 정보 교환에 제한이 있다. 그런데 우리나라는 가입자들 개인 질병정보를 보험회사에 넘겨주려고 한다. 프라이버시 문제도 있고 무엇보다도 질병정보가 공개되면 이를 빌미로 보험료를 높여 받거나 아예 가입을 거부할 수도 있다. 더 큰 문제는 실손형 보험이 확산되면 보험회사들이 병원 진료에 개입하게 된다는 것이다."

- 영화 '식코'에 보면 보험회사가 진료를 거부해 수술을 받지 못하는 환자들 이야기가 나온다. 어떻게 그런 일이 벌어지는 것인가. "우리나라에서는 아픈 사람이나 환자를 경멸하는 용어가 없는데 식코(sicko)라고 하면 쓸모없는 사람 정도의 의미로 쓰인다. 히스패닉 사람들이 속어로 쓰는데 그만큼 한번 아프면 다시 사회로 복귀하는 게 힘들다는 이야기다. 의료보험 혜택을 받지 못하는 사람들이 미국에 4800만명, 전체 인구의 20% 규모다. 해마다 1만8천명이 해마다 병원 문턱도 밟지 못하고 죽는다. 민영 의료보험에 가입된 2억5천만명의 사람들도 상황도 크게 다르지는 않다. 이를테면 백혈병인데 보험회사가 골수이식을 못하게 하고 치료만 하게 한다거나 의사가 보험회사와 논의 없이 임의로 진료를 했을 경우 진료비를 못 내겠다고 버티는 경우도 있다. 그래서 의료 소송이 끊이지 않는다. 의사들은 보험회사에서 시키는 대로 했는데 억울할 수밖에 없다. 보험회사들은 소송을 당하면 맞소송을 걸고 최종 승소하기까지 몇 년씩 걸리거나 중간에 적당히 합의하고 끝내는 경우도 많다."

- 보험회사와 병원이 직접 계약을 맺거나 환자 유인과 알선행위를 허용해야 한다는 주장도 나온다. 병원 광고를 허용하자는 주장도 있다. "실손형 보험이 도입되면 당연히 그렇게 가게 된다. 이를테면 삼성생명에 가입하면 어느 병원에 가야 보험 혜택을 받을 수 있다고 한다. 결국 병원 줄 세우기가 되고 우리랑 계약을 하지 않으면 환자를 보내지 않는다고 병원을 위협할 수 있게 된다. 지금은 건강보험 심사평가원이 병원과 가격 계약 맺고 심사 평가를 하는데 이제 그걸 보험사가 하게 된다. 보험회사가 병원을 쥐고 흔들게 되고 과소치료 강요하게 된다. 이게 미국에서 벌어지고 있는 일이다."

- 미국에도 공적 의료보장제도는 있지 않나. "65세 이상 노인의 경우 메디케어가 있고 저소득 계층을 위한 메디케이드가 있다. 이건 그야말로 최소한의 시스템이다. 메디케이드로 혜택받는 사람은 2.8% 밖에 안 된다. 나머지는 모두 민영 의료보험에 가입하거나 아예 보험 혜택을 받지 못한다. 미국 의료 체계도 장점이 있다고 이야기하는 의사들이 있는데 의사 면허증을 찢어버리라고 말하고 싶다. 물론 미국은 응급실에 실려가면 일단 공짜로 치료는 해준다. 평소에는 치료를 못 받다가 거의 죽을 때쯤 해서 응급실 실려 가서 공짜로 치료 받는 게 과연 제대로 된 의료 시스템인가. 그게 과연 의사가 할 말인가. 미국은 메디케어나 메디케이드라도 있지만 우리나라는 건강보험을 제외하면 거의 아무 것도 없다. 건강보험까지 무너지면 미국보다 훨씬 끔찍한 상황을 맞게 될 것이다."

- 우리나라도 민영 의료보험이 활성화 되면 그나마 있는 건강보험에 대한 불만이 더 높아질 것 아닌가. 건강보험에서 빠져 나가겠다는 사람들이 늘어나고 장기적으로는 건강보험 가입을 의무에서 선택사항으로 바꾸게 될 가능성도 있나. "극단적인 가정이지만 이명박 정부가 가는 방향이 바로 그 방향이다. 건강보험이 싫은 사람은 민영 의료보험으로 가고 건강보험은 껍데기만 남게 된다. 경제개발협력기구(OECD) 의료보장 수준이 73% 정도다 공립 의료기관 비율은 75% 정도 된다. 우리나라는 보장 수준이 50%, 공립 의료기관은 8% 정도다. 그나마 이 정도 보장이 되는 것은 모든 병원을 비영리 병원으로 하고 건강보험을 의무가입 하도록 하고 병원에는 건강보험 당연지정제를 두고 있기 때문에 가능한 것이다. 그런데 이 가운데 두 개를 날리겠다는 거다. 영리 병원을 허용하고 민영 의료보험을 허용하고 결국에는 의무가입도 깨지게 되는 수순이다. 이른바 강부자, 고소영씨들은 나는 건강보험 안 되는 고급 병원에 가는데 건강보험을 왜 내느냐고 주장할 것이다. 그렇게 상위 12%가 빠져 나가면 건강보험 재정이 절반으로 줄어들게 된다. 가뜩이나 열악한 건강보험 재정이 파탄난다는 이야기다."

- 영리병원의 개념을 다시 정리해 달라. 지금도 모든 병원이 다 영리병원 아닌가. "물론 지금도 병원이 돈벌이에 혈안이 돼 있는 건 맞다. 다만 지금은 병원 안에서 번 돈은 병원 안에서만 쓰도록 돼 있다. 주식이나 채권으로 바깥에 주지 말라는 것이다. 그런데 만약 병원이 주식을 발행할 수 있도록 하면 주주들이 돈을 벌게 된다. 우리나라에서도 벌써부터 일부 치과나 소아과가 프랜차이즈 사업을 벌이고 있다. 이런 병원들 보면 의사 말고 코디가 따로 있다. 경영지원시스템이라고 부르는데 이들이 환자들에게 추가 진료를 권유하고 수익을 높이는 일을 맡는다. 이를테면 이것도 하나 하시죠, 이런 주사 한번 맞아보시죠 하는 식이다. 극단적인 사례로 미국에서는 영리병원의 경우 신장투석 환자의 사망률이 비영리병원보다 20%나 높다는 통계가 있다. 적절한 시기에 신장이식 수술을 해야 하는데 병원에서는 수술 보다는 신장투석을 추천한다. 신장이식을 하고 나면 병원에 올 일이 없기 때문이다. 그래서 신장투석을 계속해서 받고 더 많이 죽게 된다. 통계적 오류는 있을 수 있지만 결코 터무니없는 소리는 아니다."

- 영리병원이 허용되면 영리병원으로 전환할 병원은 어느 정도나 될 것으로 예상하는가. "영리병원 허용과 건강보험 당연지정제 폐지는 동전의 양면처럼 맞물려 돌아간다. 영리병원으로 빠져 나가는 비율을 대략 5% 정도로 예상하고 있지만 구체적인 자료는 없다. 정부는 별로 안 나갈 거라고만 한다. 정부 역시 아무런 전망도 근거도 없다. 그러면서 반대하는 사람들에게 근거를 대라고 한다. 우리가 왜 근거를 대야 하는가."

- 영리병원의 진료비는 어느 정도 될 것으로 예상하는가. "연세대 병원에 외국 환자들을 대상으로 하는 포리너 클리닉이 있는데 진료 수가가 평균 4배 정도 된다. 감기 치료가 일반 병원은 1만3천원인데 거기는 6만원이다. 약값까지 치면 8만원 정도다. 건강보험을 적용 받으면 일반 병원에서는 약값까지 해서 5천원 정도면 되니까 거의 13배쯤 차이나는 셈이다. 맹장수술 한번 받으면 1천만원 나온다는 게 괜한 소리가 아니다. 지금은 40만원 정도 나오는데 영리병원에서는 13배 이상, 1인실 이용하고 며칠 입원하면 1천만원이 훌쩍 넘을 수도 있다. 지금은 병원 못가서 죽는 사람은 없는데 건강보험 도입되기 전에는 있었다. 그때는 의사 개업하고 2~3년 안에 빌딩 못 올리면 바보라고 했었다. 과연 그게 정상적인 사회인가."

- 그런데 의료 산업화를 주장하는 사람들은 시장원리에 맡겨야 한다고 이야기한다. 시장원리에 맡겨야 경쟁이 되고 서비스도 좋아지고 가격도 내려갈 것이고 터무니없이 비싸게 받으면 환자들이 안 갈 테니 적정 가격이 형성되지 않겠느냐는 논리에서다. "다시 강조하지만 우리나라는 공립병원이 8% 밖에 안 된다. 나머지 92% 가운데 얼마나 빠져 나갈 것인지는 아무도 모른다. 뱀파이어 효과가 생긴다. 불 껐다가 켜면 누가 뱀파이어인지 알 수 없기 때문에 다들 서로 물어뜯으려고 한다. 하나둘씩 빠져 나가다 보면 걷잡을 수 없게 된다. 결국 너도 나도 의료 수가를 올리게 되고 건강보험 수가도 덩달아 압력을 받게 된다. 경쟁을 할수록 서비스가 좋아진다고 하지만 사실 좋아지는 건 의료 수준이 아니라 그야말로 서비스뿐이다. 로비를 넓히고 엘리베이터를 고치고 병실을 꾸미고 그야말로 숙식업소로 가는 거다."

- 건강보험 재정이 열악한 것도 사실 아닌가. 일부에서는 건강보험의 재정 안정화를 위해 보장 범위를 필수의료에 한정하자는 이야기도 나온다. "필수의료와 고급의료라는 구분 자체에 문제가 있다. 고급의료라는 건 애초에 없다고 생각한다. CT나 MRI 촬영은 처음에는 고급의료였지만 이제는 필수의료가 됐다. 새로운 기술이 평범한 기술이 되는 건 2년도 안 걸린다. 양전자 자기공명이라고 부르는 PET 같은 경우만 해도 지금은 보편화됐다. 고급의료라고 건강보험에서 제외하면 제대로 진료를 할 수 없게 된다. 엑스레이만 찍고 말 것인가. 일부에서는 미용성형이나 보약, 치과진료 같은 걸 이야기하는데 그건 민영 의료보험에서도 안 한다. 그게 계지 무슨 보험인가. 고급의료라는 건 건강보험 축소를 위한 핑계일 뿐이다. 고급의료라는 건 사실 의료영역이 아닐 수도 있다. 민영 의료보험에 가입할 수 있는 능력있는 사람은 제대로 치료받겠지만 건강보험 밖에 가입할 수 없는 사람은 기초적인 치료만 받게 될 수도 있다."

- 의료 산업화가 경쟁력을 높이고 의료수지 적자를 줄일 수 있을 거라는 기대도 있는데. "해외 의료지출이 1조원이라는 이야기가 나오는데 이건 아무런 근거도 없는 이야기다. 삼성의료원 이종철 원장이 언젠가 인터뷰에서 대략 1조원쯤 될까 이 정도로 이야기했는데 모든 언론이 이를 인용하고 있다. 대한병원협의회에서는 이런 자료 낸 적이 없다고 한다. 보건산업진흥원과 한국은행 추계로는 500억원로 보고 있다. 많이 잡아야 1천억원이다. 게다가 여기에는 원정 출산이 상당부분 포함돼 있다. 그런데 최근 대한무역진흥공사가 1조원이라고 또 듣도 보도 못한 수치를 끄집어 냈다. 오래 된 사기를 새로운 사기로 포장한 셈이다."

- 인구 고령화가 진행되면서 건강보험의 재정적자는 불가피한 상황이다. 대안이 있나. "필요하다면 보험료를 올려야 한다. 그게 민영 의료보험을 활성화하는 것보다 훨씬 나은 대안이다. 사실 보험료를 안 올려는 대안도 있다. 보험료를 5:5로 내는 나라는 우리나라밖에 없다. 회사가 5, 가입자가 5를 낸다. 대만은 6:3:1이다. 회사가 6: 가입자는 3, 정부가 1을 낸다. 유럽의 스칸디나비아 나라들은 9:1이고 프랑스는 8:2다. 우리나라는 가뜩이나 복지부문 정부 지출이 OECD의 3분의 1 수준인데 건강보험의 재정 적자를 이야기하는 건 우스운 일 아닌가."

- 이르면 올해 5월부터 GMO 식품이 수입될 거라고 한다. 논란이 많지만 아직 GMO가 위험하다는 과학적인 근거는 없지 않나. 일부 시민단체는 현실적인 이유로 GMO 식품의 수입 거부는 문제가 있다고 보고 수입 거부보다는 표시제도를 강화하자고 주장한다. "FTA 협상 과정에서 일부 교역 조건을 완화하는 것을 조건으로 GMO 식품 수입을 허용하는 거래를 했다는 증거가 있다. 의류 수출을 위해 GMO 식품을 들여오기로 한 것이다. 유럽은 가공식품이든 뭐든 GMO 식품 첨가 여부를 표시하도록 돼 있는데 우리는 모르고 먹고 있다. 위험성이 밝혀진 바 없다고 하지만 밝혀지지 않은 바도 없다. 토마토를 탱탱하게 보이려고 토마토에 넙치 유전자를 집어넣는 경우가 일반적인데 정작 위험성을 검사할 때는 이 결합 식품의 위험성을 검사하는 게 아니라 넙치 유전자의 유해성을 검사한다. 그만큼 위험성 검사가 엉터리로 이뤄지고 있다는 이야기다. 이해를 돕기 위해 말하자면 왜 GMO 쌀은 있는데 GMO 밀은 없는가. 몬산토에서 개발은 거의 끝냈는데 소비자 단체 발발이 거세서 잠정 중단한 상태다. 터미네이터라고 불리는 유전자가 있다. 한번 뿌리고 수확해서 다시 뿌리면 안 열리는 유전자다. 특허를 보호하기 위해 종자를 뿌릴 때마다 다시 사도록 하기 위해서인데 문제는 이 유전자가 날아가서 다른 식물과 이종 교배가 되면 어떻게 할 것이냐다. 무슨 말이냐면 아예 종자 번식을 못하게 된다는 것이다. 끔찍한 일이다."

- 의약품 특허도 문제 아닌가. 한미 FTA에 외국 제약회사들 이해관계를 반영하는 조항이 많은데. "특허라는 게 한 사람이 개발한 과학기술을 무덤까지 갖고 가지 않게 일정 기한이 지나면 공개하고 인류의 재산으로 만들기 위한 것이다. 그런데 그 이익이 개발한 사람에게 돌아가는 게 아니라 주주들에게 돌아간다. 세계보건총회에서 나라마다 GDP의 몇 %씩 갹출을 해서 글로벌 펀드를 만들고 항생제를 개발하고 특허를 공개해 저렴한 가격에 필수 의약품을 공급하자는 의견이 나왔다. 그런데 미국이 반대해서 무산됐다. 더 정확하게는 미국에 있는 다국적 제약회사들이 반대했다. 세계적으로 완전히 박멸된 질병이 소아마비다. 소아마비 백신을 개발한 조나단 솔크가 특허를 포기한 덕분에 세계 어디에서나 이 백신은 100원 정도면 접종할 수 있다. 그런데 제약회사들은 특허를 20년도 모라자 더 연장하려고 한다. 의약품 비용은 해마다 13.5%씩 오른다. 물가 상승률 3.5배다. 몇몇 제약회사의 이익을 위해 세계 모든 사람들이 부담을 짊어지고 있는 셈이다."

- 조류독감 치료제 타미플루의 경우가 좋은 사례가 될 것 같다. 정말 중세의 페스트처럼 인류의 3분의 1이 죽는 그런 끔찍한 일이 벌어질 수도 있나. 특허를 공개해서 타미플루를 대량생산을 해야 한다는 주장도 나오는데 가능성이 있다. "학자들은 페스트 못지 않은 위험한 전염병이 될 수도 있다고 우려하고 있다. 타미플루는 유일한 조류독감 치료제다. WHO는 인구의 15% 이상 타미플루를 확보할 필요가 있다고 권고하고 있다. 문제는 생산이 한정돼 있어 2020년이 돼야 그 정도를 확보할 수 있다는 것이다. 물량이 나오는 족족 사재기를 해서 구하기도 어려운 상황이다. 우리나라도 40만개, 1% 정도를 확보하는데 그쳤다. 다행히 사스처럼 그냥 지나가면 다행인데 그렇지 않을 경우 끔찍한 재앙이 될 수 있다. 특허를 풀면 좋겠지만 특허를 갖고 있는 회사가 길리아드 사이언스인데 이 회사의 최대 주주이자 전직 최고경영자가 바로 현재 미국 국방장관인 도널드 럼스펠드다. 가만 앉아있으면 돈 벼락을 맞을 수 있는데 이걸 내놓으려고 하겠는가."

- 미국 소고기와 광우병 이야기를 하지 않을 수 없다. FTA 찬성론자들은 흔히 미국 사람들 다 먹는 소고기가 뭐가 문제냐고들 말한다. 좀 더 신중한 사람들도 광우병의 위험을 간과해서는 안 되겠지만 지나치게 과장할 필요는 없는 것 아니냐고 한다. "확실한 건 인간 광우병의 잠복기가 10년이라는 것이다. 영국에서도 광우병이 1988년 처음 발생하고 인간 광우병은 1997년에 처음 나타났다. 미국의 경우 2013년이 돼 봐야 알 수 있다. 영국에서도 농림부 장관이 나와서 소고기 시식도 하고 아무 문제 없다고 떠들어 댔지만 결국 수많은 사람이 죽었다. 과장이 아니다. 언젠가 조선일보 칼럼에서 어떤 대학 교수가 내 아들도 미국에서 소고기 먹고 있다고 말하던데 그 사람은 아마 초등학교 생물학부터 다시 공부하는 게 좋겠다. 10년 지나서 다시 이야기하자. 유럽에서는 미국산 소고기 수입 거의 안 한다. 유럽은 동물성 사료를 금지했는데 미국은 여전히 교차 오염 위험성이 있다. 소에게 돼지를 먹이고 돼지에게 소를 먹이고 그런데 만약 소 안에서 소화되지 않은 돼지를 돼지가 먹고 돼지 안에서 소화되지 않은 소를 소가 먹는다고 생각해 봐라. 위험은 과장되는 것이 아니라 제대로 알려지고 있지 않다. 미국에서 사상 최대의 소고기 리콜 사태가 벌어졌는데 여전히 우리는 소고기 수입하고 FTA 체결하자고 한다. 도대체 미국만 먹고 아무도 안 먹는 미국 소고기를 왜 우리나라는 수입해야 하는가."

- 만약 소고기를 수입해 와도 아무도 안 먹을 수도 있지 않을까. 일본처럼 말이다. "언젠가 소시지를 마트에서 산 적이 있는데, 햄 말고 밀가루 들어간 길죽한 소시지였는데 점원이 요즘 이런 소시지를 누가 먹느냐고 묻더라. 이런 소시지는 어린이집에서 밖에 안 사간다는 이야기다. 어린이집에서는 가장 싼 걸 먹인다는 이야긴데 놀랍지 않은가. 만약 미국산 소고기가 들어오면 가장 먼저 이런 곳에 들어가지 않을까. 내 자식에게 먹이고 싶지 않은 음식을 다른 자식들에게는 먹인다. 결국 모두가 먹게 된다. 이런 소고기를 누가 수입하는 것일까. 급식업체들인 삼성에버랜드와 CJ푸드시스템 같은 회사들이다. 값싼 소고기를 들여오면 급식비를 내릴까, 천만의 말씀이다. 어디 소고기를 쓰는지 알게 뭔가. 급식업체 뿐만 아니라 식당이나 가공식품 등 곳곳에 들어가게 된다. 결국 그 과정에서 누가 돈을 챙기는가. 미국에서는 다국적 식품회사들, 우리나라에서는 재벌들이다. FTA라는 게 사실 미국의 자본과 한국의 자본이 뜨겁게 연대하는 과정이다."
Posted by 디오디오

태연 - 만약에

음악 2008/04/11 18:34
Posted by 디오디오
TAG 음악

화려한 휴가

기타 2007/07/29 00:39
5월, '화려한 휴가'의 기록

80년 5월 17일, 광주 상무대 전투교육사령부에서 공수부대 천여명이 작전개시 명령을 기다리고 있었다. 작전의 이름은 '화려한 휴가' 였다.

80년 5월 18일. 나는 광주에 있었다. 어머니께서는 태어난지 7개월이 채 되지 않은 나를 데리고 요양차 친정에 머무르고 계셨던 것이다. 전남대 정문 앞 외가에서 나는 5월 18일을 맞았다.

<블러디선데이>는 아일랜드의 민중 유혈사태를 다룬 영화이다. 공교롭게도, 광주가 처참하게 찢어발겨졌던 5월의 그날 역시 일요일이었다. 지구 반대편에서 벌어졌던 피의 역사는 치밀하게 연구되고 기록되는 마당에, 이 땅에서 우리의 혈육들이 살상당했던 기억들은 조직적으로 지워지고 망각되어 버리는 실태이다. 우습고 창피하고, 무서운 일이다.

광주의 아들 딸들이라고 불리웠던, 386세대들이 권력의 핵심에 등장한 작금에 이르러서도 전두환 군사정권에 비해 나아진 점은 찾아볼 수 없다. 아니, 오히려 더 나빠졌다. 5월의 정신은 한낮 정권의 유세거리로 전락해버린채 망령이 되어 대기를 맴돌고 있다. 광주의 피를 야기했던 군부조직과 거기에 영합했던 악덕 언론들은 여전히 배를 두들기며 호황을 누리는 세상이다.

무엇보다도 광주의 피를 묵인했던 지역감정이 여전히 진행형으로 있다는 사실은 매우 중요하다. 이는 대부분 광주에 대한 무지에서 비롯된다. 왜 광주가 싸워야만 했는지, 피를 흘려야만 했는지, 그리고 왜 김대중에게 아낌없는 지지를 보낼 수 밖에 없었는지 다른 지역의 사람들은 잘 알지 못한다.

다만 여기에서 광주에 대한 무지가 아니라, 모든 것을 충분히 잘 알고 있음에도 불구하고 자신의 안위와 삶의 영락을 위해 눈과 귀를 가리고 부조리를 허락했던 사람들은 논외로 하고자한다. 거론될 가치가 없는 인종들이기 때문이다. 타락한 대중은 타락한 독재자보다 수천배는 더 위험하다. 대한민국의 현대사가 그것을 철저하게 고증하고 있다.

지금부터 참고문헌들의 기록들을 통해 환기시키고자 하는 것은 전두환과 그의 공수부대가 '화려한 휴가'라고 일컬었던 5월의 참상들이다. 그 모습들은 믿을 수 없을만치 잔인하고 처참해서 읽고 보기가 불편하기 이를 데 없을 것이다. 그럼에도 불구하고 내가 구태여 자료들을 날짜별로 구분하고 정리하는 '바보같은' 수고를 아끼지 않는 이유는 매우 단순하다. 5월의 진실이 집단의 이익 앞에 왜곡되어 잊혀져가고 있기 때문이다. 대부분의 자료들이 의도적으로 은폐되고 폐기되어 사라져버린 마당에, 우리는 이 진실의 단초들을 더욱 더 굳건하게 부여잡아야만 할 것이다.

이곳을 방문하는 이들에게 광주와 지역감정을 이해하는데 미력하나마 도움이 될 수 있다면 정말이지 여한이 없겠다. 무지에서 벗어나 광주를 똑똑히 바라보자. 그곳에 무엇이 보이는가.

[화려한 휴가의 기록]

5월 17일

밤 11시 40분, 문공장관 이규현은 5월 17일 24시를 기해 비상계엄을 전국으로 확대한다고 발표했다. 계엄 확대가 발표되고 두 시간이 지난 후, 전남대와 조선대 캠퍼스에 특전사가 투입되었다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)

5월 18일

오전 10시, 휴교령이 내린 상태에서 전남대 정문 앞에 모여든 학생 100여명과 무장 공수대원이 대치하였다. 200-300명 정도로 수가 불어나자 학생들은 "계엄해제" "계엄군 물러가라" "휴교령 철회하라" 라는 구호를 외치기 시작했다. 곧 대치 중이던 공수부대 책임자가 "돌격 앞으로" 라는 명령을 내렸고, 공수대원들은 학생들에게 파고들면서 곤봉을 휘둘렀다. 곤봉은 쇠심이 박힌 살상용 곤봉으로, 이를 맞은 학생들이 피를 흘리며 쓰러졌다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)

"공수부대 병사들은 마음껏 모든 가능한 폭력을 행사하였다. 첫날부터 대검을 사용하였고, 지나친 폭력에 항의하는 할머니, 할아버지들에게 입에 담지 못할 욕을 해대며 무지막지하게 구타하고, 여성들에게 폭행하고 옷을 찢고 심지어 젖가슴을 대검으로 난자하였다."
- 최정운 <오월의 사회과학> (풀빛, 1999)

"공수 놈들이 여고생을 붙잡고 대검으로 교복 상의를 찢으면서 희롱하고 있었다. 그 광경을 보고 있던 60살이 넘어보이는 할머니 한 분이 "아이고! 내 새끼를 왜들 이러요?" 하면서 만류하자 공수놈들은 "이 씨팔 년은 뭐냐, 너도 죽고 싶어?" 하면서 군화발로 할머니의 배와 다리를 걷어차 할머니가 쓰러지자 다리와 얼굴을 군화발로 뭉게버렸다. 그리고 그들은 여학생의 교복 상의를 대검으로 찢고 여학생의 유방을 칼로 그어버렸다. 여학생의 가슴에서는 선혈이 가슴아래로 주르르 흘러내렸다."
-박남선 <피고인에게 사형을 선고한다> (샘물, 1988)

5월 19일

"5월 19일에 저질러진 공수부대의 만행은 어찌나 잔인했던지 진압하러 나온 경찰조차 시민들에게 울먹이면서 "제발 집으로 돌아가라, 공수부대에게 걸리면 다 죽는다"고 애원할 정도였다."

"주위의 노인들이 공수대원의 폭력을 만류하자 그들은 노인들의 머리를 곤봉으로 후려쳤다. 노인들도 머리에서 피를 뿜으며 쓰러졌다. 이런 모습을 도망치며 바라본 시위 군중들은 어디서 그런 힘이 솟았는지 일시에 돌아섰다. 그리고는 "좋다, 다 죽여라!" 하면서 공수부대에 정면으로 달려들었다"
- 전남사회운동협의회 편, 황석영 기록 <죽음을 넘어 시대의 어둠을 넘어> (풀빛, 1985)

"어느 할아버지는 "저럴 수가 있느냐, 나는 일제 때에도 무서운 순사들도 많이 보고, 6.25 때 공산당도 겪었지만 저렇게 잔인하게 죽이는 놈들은 처음 보았다. 학생들이 무슨 죄가 있길래 저러는가. 죄가 있다고 해도 저럴 수는 없다. 저놈들은 국군이 아니라 사람의 탈을 쓴 악귀들이야." 하면서 통곡했다. 어느 중년의 사내는 "나는 월남전에는 참전해서 베트콩도 죽여봤지만 저렇게 잔인하지는 않았다. 저런 식으로 죽일바엔 그냥 총으로 쏴 죽이지. 저 놈들은 죽여버려야 해" 하면서 오열을 터뜨렸다. 온 거리는 피의 강, 울음의 바다가 되었다."

"로타리 부근 전투에서 머리가 으깨지고 팔이 부러져 온통 피범벅이 된 부상자를 급히 병원으로 이송중이던 택시기사에게 공수대원이 부상자를 내려놓으라고 명령했다. 기사는 안타깝게 "당신이 보다시피 지금 곧 죽어가는 사람을 병원으로 운반해야 되지 않겠느냐" 라고 호소하자 그 공수대원은 차의 유리창을 부수고 운전기사를 끌어내려 대검으로 무참하게 배를 찔러 살해했다. 이런 식으로 최소한 3명의 운전기사가 살해당했는데, 이는 다음날인 20일, 또 하나의 기폭제였던 차량시위의 직접적인 계기가 된다."
- 전남사회운동협의회 편, 황석영 기록 <죽음을 넘어 시대의 어둠을 넘어> (풀빛, 1985)

5월 20일

대검만으로는 모자랐던 걸까. 20일 오후부터는 심지어 화염방사기까지 사용하였다. 2시 30분경 공수부대는 화염방사기를 쏘아 여러 명의 시민들이 그 자리에서 타 죽었다.
- 최정운 <오월의 사회과학> (풀빛, 1999), 강준만 <한국 현대사 산택> (인물과 사상, 2003)

"시민들은 혹시나 자신들의 운명에 관한 새로운 소식이 TV를 통해 방영되지 않을까 기대하면서 모두 열심히 시청하였지만 TV에서는 아무런 상관도 없는 연속극이나 오락프로만 아무 일도 없었다는 듯이 방영되고 있었다. 그들은 텔레비젼을 보며 이글이글 타오르는 분노를 느꼈다. 한 쪽에서는 죄 없이 같은 동포가 절규하며 죽어가고 있는데, 저 텔레비젼의 다리를 흔들어 대는 춤은 누구를 위한 것인가 하는 배신감이었다."
- 전남사회운동협의회 편, 황석영 기록 <죽음을 넘어 시대의 어둠을 넘어> (풀빛, 1985)

MBC 이외에도 KBS와 세무서도 불에 탔다. 신군부는 이 방화들을 '폭도론'의 증거로 TV 등을 통해 계속 보여주었다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)

"전남대에서 신역까지 도보로 이동하면서 아스팔트와 건물을 향해 사격을 실시한다. 트럭 위에서는 M60이 엄호사격을 하면서 한 발 한 발 신역을 향해 다가간다. 사병들을 향해 고함치기 시작했다. 후퇴는 없다. 후퇴하면 모두 쏴죽인다."
- 광주매일 정사 5.18 특별 취재반 <10일간의 항쟁> (사회평론, 1995)

5월 21일

오전 10시경 금남로에는 10만이 넘는 시민들이 모여 있었다. 시민들은 일단 정오까지 공수부대를 시외곽으로 철수시키겠다는 약속을 믿고 기다리는 중이었다. 약속한 정오가 지나도 아무런 변화가 없었다. 오후 1시 정각, 건물 외부에 설치된 확성기를 통해 애국가가 울려퍼지기 시작했다. 그건 공수부대의 집단 발포를 알리는 신호였다. 광주시민들을 몰살시키려는 것이었을까. 시민들은 공수부대의 집단 발포를 정면으로 맞고 쓰러지기 시작했다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003) 광주매일 정사 5.18 특별 취재반 <10일간의 항쟁> (사회평론, 1995)

"공수놈들은 같은 동족을 살상하고도 쓰러진 사람들을 옮기지 못하도록 연발로 위협사격을 해대었다. 아직도 공수부대놈들의 사격선 부근에서 부상한 채로 살려달라고 외치는 시민들의 애원소리는 처절했고, 이는 그것을 바라보는 시민들의 피를 끓게했다. 공수놈들은 아직 죽지 않고 아스팔트 바닥 위에서 살려달라고 애원하는 시민들을 구하려고 뛰어나가는 시민들에게조차 사격을 가해 사살해버렸다. 부근 건물의 벽에 바짝 붙어서 이 광경을 보고 있던 시민들은 모두 울고 있었다."
-박남선 <피고인에게 사형을 선고한다> (샘물, 1988)

"순식간에 금남로는 피와 통곡의 바다가 되었다. 공수부대는 도청과 주변의 건물에 숨어 보이는 사람들마다 져격하였다. 1시 30분경에는 한 청년이 장갑차 위에서 윗통을 벗고 태극기를 높이 휘날리며 도청을 향해 '광주만세!' 를 외치며 달려들었다. 모든 시민들이 긴장되어 그를 응시하는 가운데 한 발의 총소리와 함께 피가 튀며 청년의 목이 꺽어졌다. 이 광경을 본 모든 시민들은 도저히 말로 표현할 수 없는 충격에 온몸을 떨었다. 이제는 정말 돌이킬 수 없는 '전쟁' 이었다. 시민들은 곧 총을 얻기 위해 시내, 외의 무기고로 향했다."
- 최정운 <오월의 사회과학> (풀빛, 1999)

21일 저녁, 드디어 시민군은 계엄군을 도청에서 몰아내고 점거하는데 성공한다.
- 강준만 <한국 현대사 산택> (인물과 사상, 2003)

5월 22일

22일 비공식적인 정전이 성사되고 종교 지도자들을 포함한 시민 수습위원회와 신군부 사이에 사태의 평화적 해결을 위한 대화가 시작되었다. 그러나 이날 계엄당국은 김대중을 광주폭동의 배후라고 발표했으며, 일부 특전사 지휘관들은 무력을 동원해 광주 '폭도들'을 '소탕' 해야 한다고 주장했다.
- 윌리엄 글라이스틴, 황정일 역. <알려지지 않은 역사> (중앙 M&B, 1999), 강준만 <한국 현대사 산책> (인물과 사상, 2003)

전두환은 정석환에게 "최장군의 사기가 극도로 저하되어 있을 터이니 용기를 잃지말고 분발하라고 전해달라"며 전두환 자신의 명의로 금일봉 1백만원을 최웅에게 전해달라고 지시했다.
- 정석환, <비화/ 5.18당시 정보부 전남지부장 정석환 비망록> (신동아, 1996 1월)

5월 24일

공수부대는 지원동 주남마을을 출발하여 학동과 진월동을 거쳐 시민들의 눈에 띄지 않는 야산으로 철수하던 중 진월동에 이르러 인근지역에 장난삼아 총질을 가했다. 저수지에서 멱을 감고 있던 아이들에게 집중 사격을 가하자 아이들은 둑 너머로 피신했지만, 전남중학교 1학년이었던 박광범이 머리에 총을 맞고 즉사했다. 또한 진월동 동산에서 놀고 있던 아이들에게도 무차별 집중사격을 가했다. 모두 피신했지만 신발이 벗겨져 뒤돌아섰던 효덕국민학교 4학년 전재수는 총에 맞고 즉사했다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)

전남대학교 교수들은 <대한민국 모든 지성인들에게 고함>을 발표했다. "모든 사람들은 6.25때에도 이런 참혹한 살육전은 없었다고 울부짖으며 '모두 죽자' '죽여달라' 를 외치며 짐승 같은 계엄군과 맨몸으로 싸웠습니다..... (중략) 고립된 우리 광주 시민들에게는 무엇보다도 한시가 절박합니다. 민주시민이여! 민주화를 위해, 우리의 삶을 위해 일어섭시다."
- 김정남 <동포여, 무엇을 하고 있는가> (생활성서, 2002년 12월)

5월 25일

아침 8시, 황금동 부근에서 술집을 경영하는 21세의 장계범이라는 사람이 도청 농림국장실에 쓰러지듯이 허겁지겁 들어닥치면서 어깨를 움켜쥐고는 "독침을 맞았다!"고 소리쳤다.... (중략) 독침 사건이 발생하자 도청 안의 분위기가 갑작스레 살벌해졌다. 여기저기서 간첩이 침투했다는 소문이 돌고 모두들 수군거리며 도청 안에는 불안해서 못 있겠다며 상당수가 빠져나갔다...(중략) 이 사건은 사전에 계획된 것으로서 침투정보요원들의 도청지도부 교란작전이었다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)

5월 26일

전남 도청에서 최초이자 마지막 내외신 기자회견이 열렸다. 미국의 일간지 <볼티모어 선>지의 기자 블레들리 마틴은 이 기자회견에서 만난 광주항쟁 지도부의 청년학생투쟁위원회 대변인이었던 윤상원에 대해 이렇게 말했다. "나는 이미 그가 죽을 것임을 예감했다. 그 자신도 그것을 알고 있는 듯했다. 표정에는 부드러움과 친절함이 배어 있었지만, 시시각각 다가오는 죽음의 그림자를 읽을 수 있었다. 지적인 눈매와 강한 광대뼈가 인상적인 그는 최후의 한 사람이 남을 때까지 싸우겠다고 했다."
- 임창용 <'폭동'아닌 '민주항쟁' 자리매김 큰 몫 윤상원 5.18 시민군 대변인> (서울신문 1998 9월 10일)

5월 27일 0시를 기점으로 광주의 시외 통화가 끊기자 도청에 남아있던 사람들은 계엄군이 진입할 것이라는 것을 예감했다. "고등학생들은 먼저 총을 버리고 투항해라. 우리야 사살되거나 다행히 살아남아도 잡혀 죽겠지만 여기 있는 고등학생들은 반드시 살아남아야 한다. 산 사람들은 역사의 증인이 되어야 한다. 우리는 민주주의와 민족통일의 빛나는 미래를 위하여, 항쟁의 마지막을 자폭으로 끝내서는 안된다. 자, 고등학생들은 먼저 나가라."
- 전남사회운동협의회 편, 황석영 기록 <죽음을 넘어 시대의 어둠을 넘어> (풀빛, 1985)

5월 27일

새벽 4시쯤 도청 앞은 탱크를 앞세운 계엄군에 의해 완전히 포위되었으며, 금남로를 중심으로 시가전이 벌어지기 시작했다. 계엄군의 장갑자 위에 장착된 서치라이트가 도청을 비추는 가운데 계엄군은 항복을 권유하는 최후 통첩을 방송했다. 그러나 도청 안에서는 아무런 반응이 없었고, 곧 총성이 울림과 함께 계엄군의 서치라이트가 박살났다. 다시 캄캄한 어둠이 내리깔렸고 계엄군의 일제사격이 개시되었다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)

달아나던 시민군을 살해했던 계엄군은 8명의 투항자들을 전부 사살하였다. 한 계엄군 병사는 한쪽 발을 시민군 포로의 등에 올려놓고 사격하면서 "어때, 영화구경하는 것 같지?"라는 농담까지 던졌다.
- 전남사회운동협의회 편, 황석영 기록 <죽음을 넘어 시대의 어둠을 넘어> (풀빛, 1985)

"시민군들이 모두 정면으로 응사하는 동안 뒷담을 넘어 들어온 3공수 특공대는 도청 건물로 잠입하여 보이는 대로 총을 난사하고 여기저기 수류탄을 까넣었다. 그리고는 확인사살까지 했다. 많은 시민군들은 특공대가 들어오는 것을 보았지만 차마 방아쇠를 당기지 못했다."
- 최정운 <오월의 사회과학> (풀빛, 1999)

그 날 이후

광주학살의 참상을 목격한 후 서울로 올라왔던 서강대생 김의기는 충격을 견디지 못하고 5월 30일 오후 5시 30분 서울 종로 5가 기독교회관에서 <동포에게 드리는 글>이라는 글을 뿌리면서 투신 자살했다.

후일, 오랫동안 집을 떠나 있어 신고가 접수되지 않은 사망자 수까지 합하면 전체 사망자 수는 2천명에 이를 것이라는 주장도 제기되었지만 확인할 길은 없었다. 공수부대원들이 처음부터 사상자수를 은폐하기 위해 사상자가 발생하는대로 트럭에 싣고 아무도 모를 곳에 파묻었기 때문에 더욱 그랬다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)

<조선일보>는 5월 25일자 사설에서 항쟁세력들을 '분별력을 상실한 군중'으로 몰아붙이고는, "......57년 전 일본 관동대지진 때 조선인 학살의 역사가 반교사적으로 우리에게 쓰라린 교훈을 주고 있다..." 며 마치 광주시민들을 무자비한 일본인 폭도들에 비유하기도 했다.
- 정운현 <'광주의 굴레' 못 벗은 한국언론> (대한매일 2001년 5월 19일)

무력감에 빠진 호남인들은 오작 말 없이 김대중에 대한 지지를 통해 그 한을 풀고자 하였지만, 인정머리 없고 광주학살에 대해 눈물 한방울 흘린 적이 없는 일부 한국인들은 그들의 그런 평화적인 선택에 대해서조차 경멸을 보내는 데에 주저하지 않았다.

신군부는 그러한 '적의 창출' 효과로 비호남, 특히 영남을 결집시켰고, 더 나아가 호남을 김대중과 등치시키면서 호남을 제외한 모든 지역의 호남에 대한 반감을 자기들을 위한 안전판으로 활용하였다. 이후 한국사회는 내내 그런 악용의 후유증을 앓게 된다.
- 강준만 <한국 현대사 산책> (인물과 사상, 2003)
Posted by 디오디오

CListCtrl FAQ

개발 2007/06/19 12:28

Celtic Wolf, Inc. Home Page
Back to Useful Information

This FAQ answers questions that are frequently asked in microsoft.public.vc.mfc about the MFC class CListCtrl and the related class CListView.

Contents:
Insertion
1. When I try to insert information in the second, third, etc. columns, with InsertItem(), it doesn't work. Why?
Appearance
2. How do I make selection appear even when control doesn't have focus?
3. How do I select the entire row?
Getting and setting item states
4. How do I get the item's selected/focused state?
5. How can I check the state of an item's checkbox
6. How do I programmatically (de)select an item?
7. How do I programmatically make an item (un)focused?
8. How do I programmatically set the state of an item's checkbox?
Preventing the user from altering item states
9. How do I prevent an item from being (de)selected?
10. How can I prevent an item from being (un)checked?
Finding items
11. How do I find the (first) selected item?
12. How do I find the item with the focus?
Columns
13. When I create my control with column 0 set for center or right justification, why is it drawn with left justification?
Sorting
14. When my sorting callback function is called, why are lParam1 and lParam2 always 0?
15. How can I sort the control when the user clicks on a column header?
Advanced
16. How can I get the contents of a control in another program?

1. When I try to insert information in the second, third, etc. columns, with InsertItem(), it doesn't work. Why?

LVITEM lvi;
::ZeroMemory(&lvi, sizeof(LVITEM));
// Insert item for col 0
lvi.mask = LVIF_TEXT;
lvi.pszText = "one";
m_ListCtrl.InsertItem(&lvi);
// Insert subitem for col 1
lvi.pszText = "two";
lvi.iSubItem = 1;
m_ListCtrl.InsertItem(&lvi);

You can't use any of the InsertItem() functions or messages to insert subitems. Instead, you must use SetItemText() (or ListView_SetItemText() or LVM_SETITEMTEXT). InsertItem() inserts the row and populates the first cell. In order to populate additional cells in that row, you must call SetItemText().

2. How do I make selection appear even when control doesn't have focus?

Use the style LVS_SHOWSELALWAYS when creating your control.

3. How do I select the entire row?

Use CListCtrl::SetExtendedStyle to set the style LVS_EX_FULLROWSELECT. Note that this requires version 4.70 or higher of the comctl32.dll.

4. How do I get the item's selected/focused state?

UINT uState = m_ListCtrl.GetItemState(iIndex, LVIS_SELECTED | LVIS_FOCUSED);
if (uState & LVIS_SELECTED)
	// Item is selected
if (uState & LVIS_FOCUSED)
	// Item has the focus

5. How can I check the state of an item's checkbox

Use CListCtrl::GetCheck() or ListView_GetCheckState()

6. How do I programmatically (de)select an item?

Select: m_ListCtrl.SetItemState(iItem, LVIS_SELECTED, LVIS_SELECTED);
Deselect: m_ListCtrl.SetItemState(iItem, 0, LVIS_SELECTED);

7. How do I programmatically make an item (un)focused?

Focused: m_ListCtrl.SetItemState(iItem, LVIS_FOCUSED, LVIS_FOCUSED);
Unfocused: m_ListCtrl.SetItemState(iItem, 0, LVIS_FOCUSED);

8. How do I programmatically set the state of an item's checkbox?

Use CListCtrl::SetCheck() or the following macro:

#ifndef ListView_SetCheckState
   #define ListView_SetCheckState(hwndLV, i, fCheck) \
      ListView_SetItemState(hwndLV, i, \
      INDEXTOSTATEIMAGEMASK((fCheck)+1), LVIS_STATEIMAGEMASK)
#endif

9. How do I prevent an item from being (de)selected?

10. How can I prevent an item from being (un)checked?

You'll need to handle LVN_ITEMCHANGING and return FALSE to allow the item to be (un)checked or (de)selected and return TRUE to disallow a change.

Here's some code that might help.

Add this to your CMyListCtrl class definition as a protected function:

// Returns TRUE if the item is checked, false if it is not or uState == 0
inline BOOL IsChecked(UINT uState) {return
(uState ? ((uState & LVIS_STATEIMAGEMASK) >> 12) - 1 : FALSE);}

Here's a sample function for handling LVN_ITEMCHANGING:

void CTestListView::OnItemchanging(NMHDR* pNMHDR, LRESULT* pResult)
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	
	// If old state is unchecked and new state is checked
	// then item is being checked.
	if ((! IsChecked(pNMListView->uOldState)) &&
		(IsChecked(pNMListView->uNewState)))
		MessageBox("Item is being checked");
	
	// If old state is checked and new state is unchecked,
	// item is being unchecked
	else if ((IsChecked(pNMListView->uOldState)) &&
		(! IsChecked(pNMListView->uNewState)))
		MessageBox("Item is being unchecked");

	// return FALSE (or 0) to allow change, TRUE to prevent
	*pResult = 0;
}//OnItemchanging

11. How do I find the (first) selected item?

First: int iItem = m_ListCtrl.GetNextItem(-1, LVNI_SELECTED);
Subsequent: iItem = m_ListCtrl.GetNextItem(iItem, LVNI_SELECTED);

12. How do I find the item with the focus?

int iItem = m_ListCtrl.GetNextItem(-1, LVNI_FOCUSED);

13. When I create my control with column 0 set for center or right justification, why is it drawn with left justification?

For some reason, the control doesn't pay any attention to the LVCOLUMN.fmt value when creating the column. However, you can change this value later by calling CListCtrl::SetColumn() (or using ListView_SetColumn or LVM_SETCOLUMN). Simply set LVCOLUMN.fmt to the desired value.

LVCOLUMN lvCol;
::ZeroMemory(&lvCol, sizeof(LVCOLUMN));
lvCol.mask = LVCF_TEXT;
lvCol.pszText = "Col0";
// Insert the column
int iCol = m_ListCtrl.InsertColumn(0, &lvCol);
// Set it to be centered
lvCol.mask = LVCF_FMT;
lvCol.fmt = LVCFMT_CENTER;
BOOL bRes = m_ListCtrl.SetColumn(iCol, &lvCol);

14. When my sorting callback function is called, why are lParam1 and lParam2 always 0?

Some versions of the documentation on CListCtrl::SortItems and LVM_SORTITEMS seem to imply that the values of lParam1 and lParam2 are the indices of the items to be sorted. This is not the case. They are the 32 bit values that can be assigned to each item via CListCtrl::SetItemData or via the lParam member of the LVITEM struct. If you have not assigned any data to these variables, then they will be zero when passed to your sort function.

15. How can I sort the control when the user clicks on a column header?

To capture the click event: Sorting the list when user clicks on column header
To draw a sort arrow on the header: Indicating sort order in header control

16. How can I get the contents of a list control in another program?

See the September 1997 Win32 Q&A by Jeffrey Richter in MSJ

Home

Posted by 디오디오
Posted by 디오디오
TAG 음악