BULK INSERT 문의 성능을 어떻게 조사합니까?


12

주로 Entity Framework ORM을 사용하는 .NET 개발자입니다. 그러나 ORM 사용에 실패 하고 싶지 않기 때문에 데이터 계층 (데이터베이스) 내에서 일어나는 일을 이해하려고합니다. 기본적으로 개발 중에 프로파일 러를 시작하고 쿼리 측면에서 코드의 일부 부분을 생성하는지 확인합니다.

내가 완전히 복잡한 것을 발견하면 (ORM이 간단한 LINQ 문에서도 신중하게 작성되지 않은 경우에도 끔찍한 쿼리를 생성 할 수 있음) 및 / 또는 무거운 (지속 시간, CPU, 페이지 읽기) SSMS로 가져 와서 실행 계획을 확인하십시오.

내 수준의 데이터베이스 지식에 적합합니다. 그러나 BULK INSERT 는 SHOWPLAN을 생성하지 않는 것처럼 보이 므로 특별한 생물 인 것 같습니다 .

나는 매우 간단한 예를 설명하려고 노력할 것이다.

테이블 정의

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)

참고 : 테이블에 다른 인덱스가 정의되어 있지 않습니다

대량 삽입 (프로파일 러에서 파악한 것, 배치 하나만)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] Int, [ImportingSystemId] Int, [FileName] NVarChar(64) COLLATE Latin1_General_CI_AS, [FileImportTime] DateTime2(7))

측정 항목

  • 항목 695 개 삽입
  • CPU = 31
  • 읽는다 = 4271
  • 쓰기 = 24
  • 지속 시간 = 154
  • 총 테이블 수 = 11500

내 응용 프로그램의 경우 읽기는 다소 커 보이지만 (SQL Server 내부에 대해서는 거의 알지 못하므로 8K 페이지 크기 및 작은 레코드 정보와 비교)

질문 : 이 BULK INSERT를 최적화 할 수 있는지 어떻게 조사 할 수 있습니까? 아니면 클라이언트 응용 프로그램에서 SQL Server로 대용량 데이터를 푸시하는 가장 빠른 방법이기 때문에 의미가 없습니다.

답변:


14

내가 알 수있는 한, 일반 인서트를 최적화하는 것과 매우 유사한 방식으로 벌크 인서트를 최적화 할 수 있습니다. 일반적으로 간단한 삽입에 대한 쿼리 계획은 그다지 유익하지 않으므로 계획이없는 것에 대해 걱정하지 마십시오. 인서트를 최적화하는 몇 가지 방법을 살펴볼 것이지만 대부분 질문에 지정한 인서트에는 적용되지 않을 것입니다. 그러나 나중에 더 많은 양의 데이터를로드해야하는 경우 도움이 될 수 있습니다.

1. 클러스터링 키 순서로 데이터 삽입

SQL Server는 종종 클러스터 된 인덱스가있는 테이블에 데이터를 삽입하기 전에 데이터를 정렬합니다. 일부 테이블 및 응용 프로그램의 경우 플랫 파일의 데이터를 정렬하고 SQL Server에 데이터가 다음 ORDER인수를 통해 정렬되었음을 알립니다 BULK INSERT.

ORDER ({열 [ASC | DESC]} [, ... n])

데이터 파일의 데이터 정렬 방법을 지정합니다. 가져 오는 데이터가 테이블의 클러스터 된 인덱스 (있는 경우)에 따라 정렬되면 대량 가져 오기 성능이 향상됩니다.

IDENTITY열을 클러스터 된 키로 사용하므로 걱정할 필요가 없습니다.

2. TABLOCK가능하면 사용하십시오

테이블에 데이터를 삽입하는 세션이 하나만 보장되는 경우에 TABLOCK인수를 지정할 수 있습니다 BULK INSERT. 이는 잠금 경합을 줄이고 일부 시나리오에서 최소한의 로깅 으로 이어질 수 있습니다. 그러나 이미 데이터가 포함 된 클러스터형 인덱스가있는 테이블에 삽입하므로이 답변의 뒷부분에 나오는 추적 플래그 610없이 최소한의 로깅을 얻지 못합니다.

만약이 TABLOCK있기 때문에, 수 없습니다 코드를 변경할 수 없습니다 , 모든 희망이 손실됩니다. 사용을 고려하십시오 sp_table_option:

EXEC [sys].[sp_tableoption]
    @TableNamePattern = N'dbo.BulkLoadTable' ,
    @OptionName = 'table lock on bulk load' , 
    @OptionValue = 'ON'

다른 옵션은 추적 플래그 715 를 활성화하는 것 입니다.

3. 적절한 배치 크기를 사용하십시오

배치 크기를 변경하여 인서트를 조정할 수있는 경우도 있습니다.

ROWS_PER_BATCH = rows_per_batch

데이터 파일의 대략적인 데이터 행 수를 나타냅니다.

기본적으로 데이터 파일의 모든 데이터는 단일 트랜잭션으로 서버에 전송되며 배치의 행 수는 쿼리 최적화 프로그램에 알려지지 않습니다. ROWS_PER_BATCH (값> 0)를 지정하면 서버는이 값을 사용하여 대량 가져 오기 작업을 최적화합니다. ROWS_PER_BATCH에 지정된 값은 실제 행 수와 대략 같아야합니다. 성능 고려 사항에 대한 자세한 내용은이 항목 뒷부분의 "설명"을 참조하십시오.

이 기사의 뒷부분에서 인용 한 내용은 다음과 같습니다.

단일 배치에서 플러시 할 페이지 수가 내부 임계 값을 초과하면 배치가 커밋 될 때 플러시 할 페이지를 식별하기 위해 버퍼 풀의 전체 스캔이 발생할 수 있습니다. 이 전체 스캔은 대량 가져 오기 성능을 저하시킬 수 있습니다. 큰 버퍼 풀이 느린 I / O 서브 시스템과 결합 될 때 내부 임계 값을 초과하는 경우가 발생합니다. 대형 머신에서 버퍼 오버 플로우를 방지하려면 대량 최적화를 제거하는 TABLOCK 힌트를 사용하지 않거나 대량 최적화를 유지하는 작은 배치 크기를 사용하십시오.

컴퓨터는 다양하기 때문에 데이터로드로 다양한 배치 크기를 테스트하여 가장 적합한 것이 무엇인지 찾아 보는 것이 좋습니다.

개인적으로 695 행을 모두 단일 배치로 삽입합니다. 배치 크기를 조정하면 많은 양의 데이터를 삽입 할 때 큰 차이를 만들 수 있습니다.

4. IDENTITY컬럼 이 필요한지 확인하십시오

데이터 모델이나 요구 사항에 대해 아무것도 모르지만 IDENTITY모든 테이블에 열을 추가하는 함정에 빠지지는 않습니다 . Aaron Bertrand는 이것에 관한 기사가있다 : 나쁜 습관을 걷어차 라 : 모든 테이블에 IDENTITY 열을두기 . 분명히하기 IDENTITY위해이 테이블 에서 열을 제거해야한다고 말하지 않습니다 . 그러나 IDENTITY열이 필요하지 않다고 판단한 경우 열을 제거하면 삽입 성능이 향상 될 수 있습니다.

5. 인덱스 또는 제약 조건 비활성화

이미 가지고있는 것과 비교하여 많은 양의 데이터를 테이블에로드하는 경우로드 전에 인덱스 또는 제약 조건을 비활성화하고로드 후 활성화하는 것이 더 빠를 수 있습니다. 많은 양의 데이터의 경우 일반적으로 데이터가 테이블에로드되는 대신 SQL Server에서 인덱스를 한 번에 모두 작성하는 것이 더 비효율적입니다. 11500 개의 행이있는 테이블에 695 개의 행을 삽입 한 것으로 보이므로이 기술을 권장하지 않습니다.

6. TF 610 고려

추적 플래그 610은 일부 추가 시나리오에서 최소 로깅을 허용합니다. IDENTITY클러스터 키 가있는 테이블 의 경우 복구 모델이 단순하거나 대량 로그되어있는 한 새 데이터 페이지에 대해 최소한의 로깅을 얻을 수 있습니다. 이 기능은 일부 시스템의 성능을 저하시킬 수 있으므로 기본적으로 켜져 있지 않습니다. 이 추적 플래그를 활성화하기 전에 신중하게 테스트해야합니다. 권장되는 Microsoft 참조는 여전히 데이터로드 성능 안내서 인 것으로 보입니다.

추적 플래그 610에서 최소 로깅의 I / O 영향

최소한으로 기록 된 대량로드 트랜잭션을 커밋 할 때 커밋이 완료되기 전에로드 된 모든 페이지를 디스크로 플러시해야합니다. 이전 체크 포인트 작업으로 잡히지 않은 플러시 페이지는 많은 랜덤 I / O를 생성 할 수 있습니다. 이것을 완전히 기록 된 작업과 대조하면 로그 쓰기에 순차적 I / O가 생성되고 커밋 된 시간에로드 된 페이지를 디스크로 플러시 할 필요가 없습니다.

로드 시나리오가 검사 점 경계를 넘지 않는 btree에서 작은 삽입 작업이고 I / O 시스템이 느린 경우 최소 로깅을 사용하면 실제로 삽입 속도가 느려질 수 있습니다.

내가 알 수있는 한, 이것은 추적 플래그 610과 관련이 없으며 최소한의 로깅 자체와 관련이 있습니다. ROWS_PER_BATCH튜닝에 대한 이전의 인용문도 이와 같은 개념을 취하고 있다고 생각합니다 .

결론적으로을 튜닝하기 위해 할 수있는 일은 많지 않을 것입니다 BULK INSERT. 삽입물에서 관찰 한 읽기 횟수에 대해서는 걱정하지 않습니다. SQL Server는 데이터를 삽입 할 때마다 읽기를보고합니다. 다음과 같은 매우 간단한 것을 고려하십시오 INSERT.

DROP TABLE IF EXISTS X_TABLE;

CREATE TABLE X_TABLE (
VAL VARCHAR(1000) NOT NULL
);

SET STATISTICS IO, TIME ON;

INSERT INTO X_TABLE WITH (TABLOCK)
SELECT REPLICATE('Z', 1000)
FROM dbo.GetNums(10000); -- generate 10000 rows

출력 SET STATISTICS IO, TIME ON:

테이블 'X_TABLE'. 스캔 카운트 0, 논리적 읽기 11428

11428이 읽은 것으로보고되었지만 실행 가능한 정보는 아닙니다. 때때로 최소한의 로깅으로보고 된 읽기 수를 줄일 수 있지만 물론 그 차이를 성능 향상으로 직접 변환 할 수는 없습니다.


12

속임수에 대한 지식 기반을 구축 하면서이 답변을 지속적으로 업데이트하려는 의도 로이 질문에 대답하기 시작할 것입니다. 바라건대 다른 사람들이이 문제를 발견하고 그 과정에서 내 지식을 향상시키는 데 도움이되기를 바랍니다.

  1. 직감 점검 : 방화벽이 상태 저장, 심층 패킷 검사를 수행하고 있습니까? 인터넷에 대해서는 그다지 많이 알지 못하지만 대량 삽입물이 원래의 것보다 약 10 배 느리다면 보안 어플라이언스가 레벨 3-7 심층 패킷 검사를 수행하고 "일반 SQL 주입 방지"를 검사 할 가능성이 있습니다 ".

  2. 일괄 처리 당 대량 삽입 할 데이터의 크기 (바이트)를 측정하십시오. 별도의 페이지 페치 및 쓰기 조작이므로 LOB 데이터를 저장하고 있는지 확인하십시오.

    이런 식으로해야하는 몇 가지 이유 :

    ㅏ. AWS에서 Elastic Block Storage IOPS는 행이 아닌 바이트로 나뉩니다.

    1. EBS IOPS 단위에 대한 설명은 Linux 인스턴스»I / O 특성 및 모니터링 에서 Amazon EBS 볼륨 성능을 참조하십시오.
    2. 특히, 범용 SSD (gp2) 볼륨 에는 "I / O 크레딧 및 버스트 성능"개념이 있으며 대량 ETL 처리에서 버스트 밸런스 크레딧을 고갈시키는 것이 일반적입니다. 버스트 지속 시간은 SQL Server 행이 아닌 바이트 단위로 측정됩니다. :)

    비. 대부분의 라이브러리 나 백서는 행 수를 기준으로 테스트하지만 실제로 해당 페이지에 기록 할 수있는 페이지 수이며이를 계산하려면 행당 바이트 수와 페이지 크기 (보통 8KB)를 알아야합니다. 하지만 다른 사람으로부터 시스템을 상속받은 경우 항상 다시 확인하십시오.)

    SELECT *
    FROM 
    sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N'YourTable'), NULL, NULL, 'DETAILED')
    

    avg_record_size_in_bytes 및 page_count에주의하십시오.

    씨. Paul White는 https://sqlperformance.com/2019/05/sql-performance/minimal-logging-insert-select-heap 에서 설명합니다 . "로 최소 로깅을 사용하려면 INSERT...SELECTSQL Server에서 총 크기가 250 개를 초과해야합니다. "1 페이지 (8 페이지) 이상이어야합니다."

  3. 검사 제한 조건 또는 고유 제한 조건이있는 인덱스가있는 경우 SET STATISTICS IO ONSET STATISTICS TIME ON(또는 SQL Server 프로파일 러 또는 SQL Server 확장 이벤트)를 사용하여 대량 삽입에 읽기 조작이 있는지 여부와 같은 정보를 캡처하십시오. 읽기 작업은 SQL Server 데이터베이스 엔진으로 인해 무결성 제약 조건이 통과되도록합니다.

  4. PRIMARYFILEGROUP 가 RAM 드라이브에 마운트 된 테스트 데이터베이스를 작성하십시오 . 이는 SSD보다 약간 빠르지 만 RAID 컨트롤러가 오버 헤드를 추가 할 수 있는지에 대한 질문을 제거합니다. 2018 년에는 그렇지 않아야하지만 이와 같은 여러 개의 차등 기준을 작성하면 하드웨어에 추가되는 오버 헤드의 양에 대한 일반적인 아이디어를 얻을 수 있습니다.

  5. 또한 소스 파일을 RAM 드라이브에도 넣습니다.

    소스 파일을 RAM 드라이브에 넣으면 데이터베이스 서버의 FILEGROUP이있는 동일한 드라이브에서 소스 파일을 읽는 경우 경합 문제가 배제됩니다.

  6. 64KB 범위를 사용하여 하드 드라이브를 포맷했는지 확인하십시오.

  7. UserBenchmark.com을 사용 하여 SSD를 벤치마킹하십시오. 이것은 :

    1. 장치에서 기대할 수있는 성능에 대해 다른 성능 애호가에게 더 많은 지식 추가
    2. 드라이브의 성능이 동일한 정확한 드라이브로 성능이 낮은 피어인지 확인하는 데 도움이됩니다.
    3. 드라이브의 성능이 같은 범주 (SSD, HDD 등)의 다른 드라이브보다 성능이 낮은 지 파악하는 데 도움이됩니다.
  8. Entity Framework Extensions를 통해 C #에서 "INSERT BULK"를 호출하는 경우 먼저 JIT를 "웜업"하고 처음 몇 가지 결과를 "버려"야합니다.

  9. 프로그램의 성능 카운터를 만들어보십시오. .NET을 사용하면 benchmark.NET 을 사용할 수 있으며 여러 기본 메트릭을 자동으로 프로파일 링합니다. 그런 다음 오픈 소스 커뮤니티와 프로파일 러 시도를 공유하고 다른 하드웨어를 실행하는 사람들이 동일한 메트릭을보고하는지 확인할 수 있습니다 (즉, 이전에 UserBenchmark.com을 사용하여 비교).

  10. 명명 된 파이프를 사용하여 localhost로 실행하십시오.

  11. SQL Server를 대상으로하고 .NET Core를 사용하는 경우 SQL Server Std Edition으로 Linux를 가동하는 것이 좋습니다. 심각한 하드웨어에서도 시간당 1 달러 미만의 비용이 듭니다. OS가 다른 동일한 하드웨어로 동일한 코드를 사용하면 OS 커널의 TCP / IP 스택에 문제가 있는지 확인할 수 있습니다.

  12. Glen Barry의 SQL Server 진단 쿼리를 사용하여 데이터베이스 테이블의 FILEGROUP을 저장하는 드라이브의 드라이브 대기 시간을 측정하십시오.

    ㅏ. 시험 전과 시험 후에 반드시 측정하십시오. "테스트 전"은 기준으로 끔찍한 IO 특성이 있는지 여부를 알려줍니다.

    비. "시험 중"측정을 ​​위해서는 실제로 PerfMon 성능 카운터를 사용해야합니다.

    왜? 대부분의 데이터베이스 서버는 일종의 NAS (Network Attached Storage)를 사용하기 때문입니다. 클라우드에서 AWS의 Elastic Block Storage는 바로 그 것입니다. EBS 볼륨 / NAS 솔루션의 IOPS에 구속 될 수 있습니다.

  13. 일부 도구를 사용하여 대기 통계를 측정하십시오. 레드 게이트 SQL 모니터 , 솔라 윈즈 데이터베이스 성능 분석기, 심지어 글렌 베리의 SQL 서버 진단 쿼리, 또는 바울 랜달의 대기 통계 쿼리 .

    ㅏ. 가장 일반적인 대기 유형은 Memory / CPU, WRITELOG, PAGEIOLATCH_EX 및 ASYNC_NETWORK_IO 일 것 입니다.

    비. 가용성 그룹을 실행중인 경우 추가 대기 유형이 발생할 수 있습니다.

  14. 비활성화 된 여러 동시 INSERT BULK명령 의 효과를 측정합니다 TABLOCK(TABLOCK은 INSERT BULK 명령의 직렬화를 강제 할 수 있습니다). 병목 현상이 INSERT BULK완료 되기를 기다리는 중일 수 있습니다 . 데이터베이스 서버의 실제 데이터 모델이 처리 할 수있는 한 많은 태스크를 큐에 넣어야합니다.

  15. 테이블 분할을 고려하십시오. 구체적인 예로 : 데이터베이스 테이블이 추가 전용 인 경우 Andrew Novick은 "TODAY"를 작성하고 FILEGROUPTODAY 및 BEFORE_TODAY라는 두 개의 파일 그룹으로 파티션 할 것을 제안 했습니다. 이러한 방식으로 INSERT BULK데이터가 오늘 의 데이터 인 경우 CreatedOn 필드를 필터링하여 모든 인서트가 단일에 도달하도록하여을 FILEGROUP사용할 때 블로킹을 줄일 수 TABLOCK있습니다. 이 기술은 Microsoft 백서 : SQL Server 2008을 사용하는 분할 된 테이블 및 인덱스 전략에 자세히 설명되어 있습니다.

  16. columnstore 인덱스를 사용하는 경우 TABLOCK102,400 행의 배치 크기에서 데이터를 끄고 로드하십시오. 그런 다음 모든 데이터를 열 저장소 행 그룹에 직접 병렬로로드 할 수 있습니다. 이 제안 (및 합리적으로 문서화 됨)은 Microsoft의 Columnstore 인덱스 에서 가져 옵니다 .-데이터로드 지침 :

    벌크로드에는 다음과 같은 내장 성능 최적화가 있습니다.

    병렬로드 : 각각 별도의 데이터 파일을로드하는 여러 개의 동시 벌크로드 (bcp 또는 벌크 삽입)를 가질 수 있습니다. SQL Server에 대한 rowstore 대량로드와는 달리, TABLOCK각 대량 가져 오기 스레드는 독점 잠금을 사용하여 별도의 행 그룹 (압축 또는 델타 행 그룹)으로 데이터를 독점적으로로드하므로 지정할 필요가 없습니다 . 를 사용 TABLOCK하면 테이블에 독점 잠금이 적용되고 데이터를 병렬로 가져올 수 없습니다.

    최소 로깅 :벌크로드는 압축 된 행 그룹으로 직접 이동하는 데이터에 대한 최소 로깅을 사용합니다. 델타 행 그룹으로 이동하는 모든 데이터가 완전히 기록됩니다. 여기에는 102,400 행 미만의 배치 크기가 포함됩니다. 그러나 대량로드의 경우 목표는 대부분의 데이터가 델타 행 그룹을 무시하는 것입니다.

    잠금 최적화 : 압축 된 행 그룹으로로드 할 때 행 그룹의 X 잠금이 획득됩니다. 그러나 델타 행 그룹으로 대량로드하는 경우 행 그룹에서 X 잠금이 획득되지만 X 행 그룹 잠금은 잠금 계층의 일부가 아니므로 SQL Server는 여전히 잠금 PAGE / EXTENT를 잠급니다.

  17. SQL Server 2016부터 인덱스 테이블에 최소한의 로깅을 위해 추적 플래그 610을 더 이상 사용할 필요가 없습니다 . Microsoft 엔지니어 Parikshit Savjani 인용 ( 강조 광산 ) :

    SQL Server 2016의 디자인 목표 중 하나는 고객을 위해 노브 나 추적 플래그가 없어도 엔진이 더 빨리 실행되도록 엔진의 성능과 확장 성을 향상시키는 것입니다. 이러한 개선의 일환으로 SQL Server 엔진 코드에서 개선 된 기능 중 하나는 데이터베이스에서 대량로드 작업을 단순 또는 대량 로그 복구 모델. 최소 로깅에 익숙하지 않은 경우 Sunil Agrawal의이 블로그 게시물을 읽고 SQL Server에서 최소 로깅이 어떻게 작동하는지 설명하는 것이 좋습니다. 대량 인서트를 최소한으로 기록하려면 여기에 설명 된 전제 조건을 충족해야합니다.

    SQL Server 2016에서 이러한 향상된 기능의 일부로 더 이상 인덱스 된 테이블에 최소한의 로깅을 위해 추적 플래그 610을 사용할 필요가 없습니다.그리고 다른 추적 플래그 (1118, 1117, 1236, 8048) 중 일부를 결합하여 히스토리의 일부가됩니다. SQL Server 2016에서 대량로드 작업으로 인해 새 페이지가 할당되면 앞에서 설명한 최소 로깅에 대한 다른 전제 조건이 모두 충족되면 새 페이지를 채우는 모든 행이 최소로 기록됩니다. 색인 순서를 유지하기 위해 기존 페이지에 삽입 된 (새 페이지 할당 없음) 행은로드 중에 페이지 분할 결과로 이동 된 행과 같이 여전히 완전히 기록됩니다. 할당 중에 페이지 잠금이 획득되어 페이지 또는 익스텐트 할당 만 기록 될 때 최소한의 로깅 조작이 작동하도록 인덱스 (기본적으로 ON)에 대해 ALLOW_PAGE_LOCKS를 ON으로 설정하는 것이 중요합니다.

  18. C # 또는 EntityFramework.Extensions (후면에서 SqlBulkCopy를 사용)에서 SqlBulkCopy를 사용하는 경우 빌드 구성을 확인하십시오. 릴리스 모드에서 테스트를 실행하고 있습니까? 대상 아키텍처가 CPU / x64 / x86으로 설정되어 있습니까?

  19. INSERT BULK 트랜잭션이 일시 중단되었는지 확인하려면 sp_who2를 사용하십시오. 다른 spid에 의해 차단되어 일시 중단 될 수 있습니다. SQL Server 차단을 최소화하는 방법을 읽어보십시오 . Adam Machanic의 sp_WhoIsActive를 사용할 수도 있지만 sp_who2는 필요한 기본 정보를 제공합니다.

  20. 디스크 I / O가 불량 일 수 있습니다. 대량 삽입을 수행하고 디스크 사용률이 100 %에 도달하지 않고 약 2 %에서 멈춘 경우 펌웨어 또는 I / O 장치 결함 일 수 있습니다. (이것은 제 동료에게 일어났습니다.) 특히 로컬 개발자 컴퓨터에서 속도 저하를 복제 할 수있는 경우 [SSD UserBenchmark]를 사용하여 다른 하드웨어 성능과 비교하십시오. (대부분의 회사에서는 IP 위험으로 인해 개발자가 로컬 컴퓨터에서 데이터베이스를 실행할 수 없기 때문에이 목록을 마지막에 넣었습니다.)

  21. 테이블에서 압축을 사용하는 경우 여러 세션을 실행하고 각 세션에서 기존 트랜잭션사용하여 시작한 후 SqlBulkCopy 명령 전에 실행하십시오.

    ALTER SERVER CONFIGURATION SET PROCESS AFFINITY CPU = 자동;

  22. 연속로드의 경우, 아이디어 백서 중 하나 인 Microsoft 백서, SQL Server 2008을 사용한 파티션 된 테이블 및 인덱스 전략에 처음 설명되어 있습니다 .

    연속 로딩

    OLTP 시나리오에서 새 데이터가 계속 제공 될 수 있습니다. 사용자가 최신 파티션도 쿼리하는 경우 데이터를 계속 삽입하면 차단 될 수 있습니다. 사용자 쿼리는 삽입을 차단할 수 있으며 마찬가지로 삽입은 사용자 쿼리를 차단할 수 있습니다.

    스냅 샷 격리, 특히 READ COMMITTED SNAPSHOT격리 수준 을 사용하면 로딩 테이블 또는 파티션의 경합을 줄일 수 있습니다 . 에서 READ COMMITTED SNAPSHOT분리, 테이블에 삽입은 활동 발생하지 않습니다 임시 데이터베이스 소위, 버전 저장소 의 tempdb가 오버 헤드 삽입에 대한 최소한의, 그러나 공유 잠금이 동일한 파티션에 사용자 쿼리에 의해 수행되지 않습니다.

    다른 경우, 데이터가 지속적으로 높은 비율로 파티션 된 테이블에 삽입되는 경우 스테이징 테이블에서 짧은 기간 동안 데이터를 스테이징 한 다음 해당 데이터가 새 파티션으로 반복 될 때까지 해당 데이터를 최신 파티션에 반복적으로 삽입 할 수 있습니다. 현재 파티션이 전달되고 데이터가 다음 파티션에 삽입됩니다. 예를 들어, 각각 30 초 분량의 데이터를 수신하는 두 개의 준비 테이블이 있다고 가정합니다. 1 분의 1 분의 1 분의 테이블과 2 분의 1 분의 2의 테이블입니다. 인서트 저장 프로시 저는 현재 인서트가있는 분의 절반을 결정한 다음 첫 번째 준비 테이블에 삽입합니다. 30 초가되면 삽입 프로시 저는 두 번째 스테이징 테이블에 삽입해야한다고 결정합니다. 그런 다음 다른 저장 프로시 저는 첫 번째 준비 테이블의 데이터를 테이블의 최신 파티션으로로드 한 다음 첫 번째 준비 테이블을 자릅니다. 30 초 후에 동일한 저장 프로시 저는 두 번째 저장 프로 시저에서 데이터를 삽입하여 현재 파티션에 넣은 다음 두 번째 준비 테이블을 자릅니다.

  23. Microsoft CAT 팀의 데이터로드 성능 안내서

  24. 통계가 최신인지 확인하십시오. 각 인덱스 빌드 후 가능하면 FULLSCAN을 사용하십시오.

  25. SQLIO를 통한 SAN 성능 조정 및 디스크 파티션이 정렬 된 기계 디스크를 사용 중인지 확인하십시오. Microsoft의 디스크 파티션 정렬 모범 사례를 참조하십시오 .

  26. COLUMNSTORE INSERT/ UPDATE성능


2

판독은 인서트 중에 확인되는 고유 한 & FK 제약 조건 일 수 있습니다. 인서트 도중에이를 비활성화 / 삭제하고 나중에 활성화 / 재 작성할 수 있으면 속도가 향상 될 수 있습니다. 이것이 활성 상태를 유지하는 것과 비교하여 전체적으로 느리게 만드는지 테스트해야합니다. 다른 프로세스가 동일한 테이블에 동시에 쓰는 경우에도 좋은 생각이 아닙니다. - 가레스 리용

대량 삽입 후 Q & A 외래 키가 신뢰할 수 없게 되면 FK 제약 조건은 옵션 BULK INSERT없이 신뢰할 수 없게됩니다 CHECK_CONSTRAINTS(내 경우 신뢰할 수없는 제약 조건으로 끝났습니다). 명확하지는 않지만 확인하고 신뢰할 수 없게 만드는 것은 합리적이지 않습니다. 그러나 PK 및 UNIQUE는 여전히 확인됩니다 ( BULK INSERT (Transact-SQL) 참조 ). - 알렉세이

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.