SQL Server에 메모리 내 OLTP 기능 채택 계획Plan your adoption of In-Memory OLTP Features in SQL Server

이 항목은 다음에 적용됩니다.예SQL Server(2014부터)예Azure SQL Database아니요Azure SQL Data Warehouse 아니요병렬 데이터 웨어하우스 THIS TOPIC APPLIES TO:yesSQL Server (starting with 2014)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

이 문서에서는 메모리 내 기능 채택이 비즈니스 시스템의 다른 측면에 영향을 주는 방식을 설명합니다.This article describes the ways in which the adoption of In-Memory features affects other aspects of your business system.

1.A. 메모리 내 OLTP 기능 채택Adoption of In-Memory OLTP features

다음 하위 섹션에서는 메모리 내 기능을 채택하고 구현하려는 경우 고려해야 할 요소를 설명합니다.The following subsections discuss factors you must consider when you plan to adopt and implement In-Memory features. 다음에서 많은 설명 정보를 확인할 수 있습니다.A lot of explanatory information is available at:

A.1 필수 조건A.1 Prerequisites

메모리 내 기능 사용을 위한 한 가지 필수 조건은 SQL 제품의 버전 또는 서비스 계층과 관련될 수 있습니다.One prerequisite for using the In-Memory features can involve the edition or service tier of the SQL product. 이 필수 조건 및 기타 필수 조건은 다음을 참조하세요.For this and other prerequisites, see:

A.2 활성 메모리 양 예측A.2 Forecast the amount of active memory

시스템에 새 메모리 액세스에 최적화된 테이블을 지원하기에 충분한 활성 메모리가 있나요?Does your system have enough active memory to support a new memory-optimized table?

Microsoft SQL ServerMicrosoft SQL Server

200GB의 데이터를 포함하는 메모리 액세스에 최적화된 테이블은 200GB 이상의 활성 메모리가 해당 지원 전용이어야 합니다.A memory-optimized table which contains 200 GB of data requires more than 200 GB of active memory be dedicated to its support. 많은 양의 데이터를 포함하는 메모리 액세스에 최적화된 테이블을 구현하기 전에 서버 컴퓨터에 추가해야 할 수 있는 추가 활성 메모리의 양을 예측해야 합니다.Before you implement a memory-optimized table containing a large amount of data, you must forecast the amount of additional active memory you might need to add to your server computer. 예측 지침은 다음을 참조하세요.For estimation guidance, see:

Azure SQL 데이터베이스Azure SQL Database

Azure SQL Database 클라우드 서비스에 호스트된 데이터베이스의 경우 선택한 서비스 계층이 데이터베이스에서 사용할 수 있는 활성 메모리의 양에 영향을 줍니다.For a database hosted in the Azure SQL Database cloud service, your chosen service tier affects the amount of active memory your database is allowed to consume. 경고를 사용하여 데이터베이스의 메모리 사용량 모니터링을 계획해야 합니다.You should plan to monitor the memory usage of your database by using an alert. 자세한 내용은 다음을 참조하세요.For details, see:

메모리 액세스에 최적화된 테이블 변수Memory-optimized table variables

메모리 액세스에 최적화되도록 선언된 테이블 변수는 tempdb 데이터베이스에 있는 기존 #TempTable에 적합한 경우도 있습니다.A table variable which is declared to be memory-optimzed is sometimes a preferable to a traditional #TempTable that resides in the tempdb database. 이러한 테이블 변수는 상당한 양의 활성 메모리를 사용하지 않고도 상당한 성능 향상을 제공할 수 있습니다.Such table variables can provide significant performance gains without using significant amounts of active memory.

A.3 메모리 액세스에 최적화된 테이블로 변환하려면 테이블이 오프라인 상태여야 함A.3 Table must be offline to convert to memory-optimized

일부 ALTER TABLE 기능은 메모리 액세스에 최적화된 테이블에 사용할 수 있습니다.Some ALTER TABLE functionality is available for memory-optimized tables. 그러나 디스크 기반 테이블을 메모리 액세스에 최적화된 테이블로 변환하기 위해 ALTER TABLE 문을 실행할 수는 없습니다.But you cannot issue an ALTER TABLE statement to convert a disk-based table into a memory-optimized table. 대신 더 많은 일련의 수동 단계를 사용해야 합니다.Instead you must use a more manual set of steps. 그다음은 디스크 기반 테이블을 메모리 액세스에 최적화된 테이블로 변환하는 다양한 방법을 소개합니다.What follows are various ways you can convert your disk-based table to be memory-optimized.

수동 스크립팅Manual scripting

디스크 기반 테이블을 메모리 액세스에 최적화된 테이블로 변환하는 한 가지 방법은 필요한 TRANSACT-SQL 단계를 직접 코딩하는 것입니다.One way to convert your disk-based table to a memory-optimized table is to code the necessary Transact-SQL steps yourself.

  1. 응용 프로그램 작업을 일시 중단합니다.Suspend application activity.

  2. 전체 백업을 수행합니다.Take a full backup.

  3. 디스크 기반 테이블의 이름을 바꿉니다.Rename your disk-based table.

  4. CREATE TABLE 문을 실행하여 새 메모리 액세스에 최적화된 테이블을 만듭니다.Issue a CREATE TABLE statement to create your new memory-optimized table.

  5. 디스크 기반 테이블에서 하위 SELECT를 사용하여 메모리 액세스에 최적화된 테이블에 삽입(INSERT INTO)합니다.INSERT INTO your memory-optimized table with a sub-SELECT from the disk-based table.

  6. 디스크 기반 테이블을 삭제(DROP)합니다.DROP your disk-based table.

  7. 또 다른 전체 백업을 수행합니다.Take another full backup.

  8. 응용 프로그램 작업을 다시 시작합니다.Resume application activity.

메모리 최적화 관리자Memory Optimization Advisor

메모리 최적화 관리자 도구는 디스크 기반 테이블을 메모리 액세스에 최적화된 테이블로 변환하는 작업을 구현하는 데 유용한 스크립트를 생성할 수 있습니다.The Memory Optimization Advisor tool can generate a script to help implement the conversion of a disk-based table to a memory-optimized table. 이 도구는 SSDT(SQL Server Data Tools)의 일부로 설치됩니다.The tool is installed as part of SQL Server Data Tools (SSDT).

.dacpac 파일.dacpac file

SSDT에서 관리하는 .dacpac 파일을 사용하여 데이터베이스를 현재 위치에서 업데이트할 수 있습니다.You can update your database in-place by using a .dacpac file, managed by SSDT. SSDT에서 .dacpac 파일로 인코딩된 스키마의 변경 내용을 지정할 수 있습니다.In SSDT you can specify changes to the schema that is encoded in the .dacpac file.

데이터베이스형식의 Visual Studio 프로젝트 컨텍스트에서 .dacpac 파일을 사용합니다.You work with .dacpac files in the context of a Visual Studio project of type Database.

A.4 메모리 내 OLTP 기능이 응용 프로그램에 적합한지에 대한 지침A.4 Guidance for whether In-Memory OLTP features are right for your application

메모리 내 OLTP 기능이 특정 응용 프로그램의 성능을 향상할 수 있는지에 대한 지침은 다음을 참조하세요.For guidance on whether In-Memory OLTP features can improve the performance of your particular application, see:

2.B. 지원되지 않는 기능Unsupported features

특정 메모리 내 OLTP 시나리오에서 지원되지 않는 기능은 다음에 설명되어 있습니다.Features which are not supported in certain In-Memory OLTP scenarios are described at:

다음 하위 섹션에서는 더 중요한 지원되지 않는 기능 중 일부를 강조합니다.The following subsections highlight some of the more important unsupported features.

B.1 데이터베이스의 스냅숏B.1 SNAPSHOT of a database

지정된 데이터베이스에서 처음으로 메모리 액세스에 최적화된 테이블 또는 모듈이 만들어진 후에는 데이터베이스의 스냅숏 을 생성할 수 없습니다.After the first time that any memory-optimized table or module is created in a given database, no SNAPSHOT of the database can ever be taken. 구체적인 이유는 다음과 같습니다.The specific reason is that:

  • 첫 번째 메모리 액세스에 최적화된 항목은 메모리 액세스에 최적화된 FILEGROUP에서 마지막 파일을 삭제할 수 없게 만듭니다.The first memory-optimized item makes it impossible to ever drop the last file from the memory-optimized FILEGROUP; and
  • 메모리 액세스에 최적화된 FILEGROUP에 파일이 있는 데이터베이스는 스냅숏을 지원할 수 없습니다.No database that has a file in a memory-optimized FILEGROUP can support a SNAPSHOT.

일반적으로 스냅숏은 빠른 테스트 반복에 유용할 수 있습니다.Normally a SNAPSHOT can be handy for quick testing iterations.

B.2 데이터베이스 간 쿼리B.2 Cross-database queries

메모리 액세스에 최적화된 테이블은 데이터베이스 간 트랜잭션을 지원하지 않습니다.Memory-optimized tables do not support cross-database transactions. 메모리 액세스에 최적화된 테이블에도 액세스하는 동일한 쿼리 또는 동일한 트랜잭션에서 다른 데이터베이스에 액세스할 수 없습니다.You cannot access another database from the same transaction or the same query that also accesses a memory-optimized table.

테이블 변수는 트랜잭션 변수가 아닙니다.Table variables are not transactional. 따라서 데이터베이스 간 쿼리에 메모리 액세스에 최적화된 테이블 변수 를 사용할 수 있습니다.Therefore, memory-optimized table variables can be used in cross-database queries.

B.3 READPAST 테이블 힌트B.3 READPAST table hint

쿼리는 READPAST 테이블 힌트 를 메모리 액세스에 최적화된 테이블에 적용할 수 없습니다.No query can apply the READPAST table hint to any memory-optimized table.

READPAST 힌트는 여러 세션이 각각 큐 처리 등 같은 작은 행 집합에 액세스하고 수정하는 시나리오에서 유용합니다.The READPAST hint is helpful in scenarios where several sessions are each accessing and modifying the same small set of rows, such as in processing a queue.

B.4 RowVersion, 시퀀스B.4 RowVersion, Sequence

  • 메모리 액세스에 최적화된 테이블에서는 열에 RowVersion 태그를 지정할 수 없습니다.No column can be tagged for RowVersion on a memory-optimized table.

  • SEQUENCE는 메모리 액세스에 최적화된 테이블의 제약 조건과 함께 사용할 수 없습니다.A SEQUENCE cannot be used with a constraint in a memory-optimized table. 예를 들어 NEXT VALUE FOR 절에 DEFAULT 제약 조건을 만들 수 없습니다.For example, you cannot create a DEFAULT constraint with a NEXT VALUE FOR clause. SEQUENCE는 INSERT 및 UPDATE 문에서 사용할 수 있습니다.SEQUENCEs can be used with INSERT and UPDATE statements.

3.C. 유지 관리Administrative maintenance

이 섹션에서는 메모리 액세스에 최적화된 테이블이 사용되는 경우 데이터베이스 관리의 차이점을 설명합니다.This section describes differences in database administration where memory-optimized tables are used.

C.1 ID 초기값 재설정, 증분 > 1C.1 Identity seed reset, increment > 1

메모리 액세스에 최적화된 테이블에는 IDENTITY 열을 재설정하는DBCC CHECKIDENT를 사용할 수 없습니다.DBCC CHECKIDENT, to reseed an IDENTITY column, cannot be used on a memory-optimized table.

메모리 액세스에 최적화된 테이블에서는 IDENTITY 열의 증분 값이 정확히 1로 제한됩니다.The increment value is restricted to exactly 1 for an IDENTITY column on a memory-optimized table.

C.2 DBCC CHECKDB는 메모리 액세스에 최적화된 테이블의 유효성을 검사할 수 없음C.2 DBCC CHECKDB cannot validate memory-optimized tables

대상이 메모리 액세스에 최적화된 테이블인 경우 DBCC CHECKDB 명령은 아무 작업도 수행하지 않습니다.The DBCC CHECKDB command does nothing when its target is a memory-optimized table. 다음 단계는 해결 방법입니다.The following steps are a work-around:

  1. 트랜잭션 로그를 백업합니다.Back up the transaction log.

  2. 메모리 액세스에 최적화된 FILEGROUP의 파일을 null 장치에 백업합니다.Back up the files in the memory-optimized FILEGROUP to a null device. 백업 프로세스에서는 체크섬 유효성 검사를 호출합니다.The backup process invokes a checksum validation.

    손상이 발견되면 다음 단계를 진행합니다.If corruption is found, proceed with the next steps.

  3. 임시 저장 용도로, 메모리 액세스에 최적화된 테이블의 데이터를 디스크 기반 테이블에 복사합니다.Copy data from your memory-optimized tables into disk-based tables, for temporary storage.

  4. 메모리 액세스에 최적화된 FILEGROUP의 파일을 복원합니다.Restore the files of the memory-optimized FILEGROUP.

  5. 디스크 기반 테이블에 임시로 저장된 데이터를 메모리 액세스에 최적화된 테이블에 삽입(INSERT INTO)합니다.INSERT INTO the memory-optimized tables the data you temporarily stored in the disk-based tables.

  6. 임시로 데이터를 저장한 디스크 기반 테이블을 삭제(DROP)합니다.DROP the disk-based tables which temporarily held the data.

4.D. 성능Performance

이 섹션에서는 메모리 액세스에 최적화된 테이블의 우수한 성능을 최대 성능 아래로 유지할 수 있는 상황을 설명합니다.This section describes situations where the excellent performance of memory-optimized tables can be held below full potential.

D.1 인덱스 고려 사항D.1 Index considerations

메모리 액세스에 최적화된 테이블의 모든 인덱스는 테이블 관련 문 CREATE TABLE 및 ALTER TABLE로 만들고 관리합니다.All indexes on a memory-optimized table are created and managed by the table-related statements CREATE TABLE and ALTER TABLE. CREATE INDEX 문을 사용해서는 메모리 액세스에 최적화된 테이블을 대상으로 할 수 없습니다.You cannot target a memory-optimized table with a CREATE INDEX statement.

처음으로 메모리 액세스에 최적화된 테이블을 구현하는 경우 기존 B-트리 비클러스터형 인덱스는 합리적이고 간단한 선택일 수 있습니다.The traditional b-tree nonclustered index is often the sensible and simple choice when you first implement a memory-optimized table. 나중에 응용 프로그램의 성능을 확인한 후 다른 인덱스 유형으로 바꾸는 것을 고려할 수 있습니다.Later, after you see how your application performs, you can consider swapping another index type.

메모리 액세스에 최적화된 테이블의 컨텍스트에서는 특수한 유형의 두 가지 인덱스인 해시 인덱스와 Columnstore 인덱스에 대한 논의가 필요합니다.Two special types of indexes need discussion in the context of a memory-optimized table: Hash indexes, and Columnstore indexes.

메모리 액세스에 최적화된 테이블의 인덱스 개요는 다음을 참조하세요.For an overview of indexes on memory-optimized tables, see:

해시 인덱스Hash indexes

해시 인덱스는 '=' 연산자를 사용하여 정확한 해당 기본 키 값으로 하나의 특정 행에 액세스하는 가장 빠른 형식일 수 있습니다.Hash indexes can be the fastest format for accessing one specific row by its exact primary key value by using the '=' operator.

  • '!=', '>' 또는 'BETWEEN'과 같은 부정확한 연산자를 해시 인덱스와 함께 사용할 경우 성능이 저하됩니다.Inexact operators such as '!=', '>', or 'BETWEEN' would harm performace if used with a hash index.

  • 해시 인덱스는 키 값 중복 비율이 너무 높은 경우에는 최선의 선택이 아닐 수도 있습니다.A hash index might not be the best choice if the rate of key value duplication becomes too high.

  • 개별 버킷 내에 긴 체인을 방지하려면 해시 인덱스에 필요할 수 있는 버킷 수를 과소평가하지 않아야 합니다.Guard against underestimating how many buckets your hash index might need, to avoid long chains within individual buckets. 자세한 내용은 다음을 참조하세요.For details, see:

비클러스터형 columnstore 인덱스Nonclustered columnstore indexes

메모리 액세스에 최적화된 테이블은 온라인 트랜잭션 처리 또는 OLTP라고 하는 패러다임에서 일반적인 비즈니스 트랜잭션 데이터의 많은 처리량을 제공합니다.Memory-optimized tables deliver high throughput of typical business transactional data, in the paradigm we call online transaction processing or OLTP. columnstore 인덱스는 분석이라고 하는 집계 및 유사한 처리의 많은 처리량을 제공합니다.Columnstore indexes deliver high throughput of aggregations and similar processing we call Analytics. 지난 수년간 OLTP와 분석 둘 다의 요구 사항을 만족하는 데 사용할 수 있는 최고의 접근 방식은 데이터 이동이 많고 어느 정도의 데이터 중복도가 있는 별도의 테이블을 사용하는 것이었습니다.In years past the best approach available for satisfying the needs of both OLTP and Analytics was to have separate tables with heavy movement of data, and with some degree of data duplication. 현재는 더 단순한 하이브리드 솔루션 을 사용할 수 있으므로 메모리 액세스에 최적화된 테이블에 columnstore 인덱스를 사용하세요.Today a simpler hybrid solution is available: have a columnstore index on a memory-optimized table.

  • 디스크 기반 테이블을 기반으로 하여 columnstore 인덱스 를 클러스터형 인덱스로도 작성할 수 있습니다.A columnstore index can be built on a disk-based table, even as the clustered index. 그러나 메모리 액세스에 최적화된 테이블에서는 columnstore 인덱스를 클러스터화할 수 없습니다.But on a memory-optimized table a columnstore index cannot be clustered.

  • 메모리 액세스에 최적화된 테이블의 LOB 또는 행 외부 열은 테이블에서 columnstore 인덱스를 만들지 못하게 합니다.LOB or off-row columns for a memory-optimized table prevent the creation of a columnstore index on the table.

  • 테이블에 columnstore 인덱스가 있는 동안에는 메모리 액세스에 최적화된 테이블에 대해 ALTER TABLE 문을 실행할 수 없습니다.No ALTER TABLE statement can be executed against a memory-optimized table while a columnstore index exists on the table.

    • 2016년 8월 현재 Microsoft는 가까운 시일 내 columnstore 인덱스 다시 만들기 성능을 향상하기 위한 계획이 있습니다.As of August 2016, Microsoft has near-term plans to improve the performance of re-creating the columnstore index.

D.2 LOB 및 행 외부 열D.2 LOB and off-row columns

LOB(Large Object)는varchar(max) 형식의 열입니다.Large objects (LOBs) are columns of such types as varchar(max). 메모리 액세스에 최적화된 테이블에 LOB 열이 몇 개 있는 정도로는 중요하기 여길 정도로 성능을 저하하지 않습니다.Having a couple of LOB columns on a memory-optimized table probably does not harm performance enough to matter. 그러나 데이터에 필요한 것보다 많은 LOB 열은 사용하지 않도록 합니다.But do avoid having more LOB columns than your data needs. 같은 조언이 행 외부 열에도 적용됩니다.The same advice applies to off-row columns. varchar(512)만으로 충분한 경우 열을 nvarchar(3072)로 정의하지 마세요.Do not define a column as nvarchar(3072) if varchar(512) will suffice.

LOB 및 행 외부 열에 대한 자세한 내용은 다음을 참조하세요.A bit more about LOB and off-row columns is available at:

5.E. 네이티브 프로시저의 제한 사항Limitations of native procs

Transact-SQL의 특정 요소는 고유하게 컴파일된 저장 프로시저에서 지원되지 않습니다.Particular elements of Transact-SQL are not supported in natively compiled stored procedures.

Transact-SQL 스크립트를 네이티브 프로시저로 마이그레이션할 때의 고려 사항은 다음을 참조하세요.For considerations when migrating a Transact-SQL script to a native proc, see:

E.1 네이티브 프로시저에서 CASE 사용 불가E.1 No CASE in a native proc

Transact-SQL에서 CASE 식은 네이티브 프로시저 내에 사용할 수 없습니다.The CASE expression in Transact-SQL cannot be used inside a native proc. 다음과 같은 해결 방법을 구현할 수 있습니다.You can fashion a work-around:

E.2 네이티브 프로시저에서 MERGE 사용 불가E.2 No MERGE in a native proc

Transact-SQL MERGE 문upsert 라는 기능과 유사점이 있습니다.The Transact-SQL MERGE statement has similarities to what is often called upsert functionality. 네이티브 프로시저에서는 MERGE 문을 사용할 수 없습니다.A native proc cannot use the MERGE statement. 그러나 SELECT, UPDATE 및 INSERT 문을 조합하여 MERGE와 같은 기능을 만들 수 있습니다.However, you can achieve the same functionality as MERGE by using a combination of SELECT plus UPDATE plus INSERT statements. 코드 예제는 다음에 있습니다.A code example is at:

E.3 네이티브 프로시저에서 UPDATE 또는 DELETE 문에 조인 사용 불가E.3 No joins in UPDATE or DELETE statements, in a native proc

네이티브 프로시저에서 Transact-SQL 문은 메모리 액세스에 최적화된 테이블에만 액세스할 수 있습니다.Transact-SQL statements in a native proc can access memory-optimized tables only. UPDATE 및 DELETE 문에서 테이블을 조인할 수 없습니다.In UPDATE and DELETE statements, you cannot join any tables. 네이티브 프로시저에서 시도가 실패하면 다음과 같이 설명하는 메시지(예: Msg 12319)가 표시됩니다.Attempts in a native proc fail with a message such as Msg 12319 which explains that you:

  • UPDATE 문에는 FROM 절을 사용할 수 없습니다.Cannot use the FROM clause in an UPDATE statement.
  • DELETE 문에는 테이블 원본을 지정할 수 없습니다.Cannot specify a table source in a DELETE statement.

하위 쿼리 유형의 해결 방법은 없습니다.No type of subquery provides a work-around. 그러나 메모리 액세스에 최적화된 테이블 변수를 사용하여 여러 개의 문에 대한 조인 결과를 달성할 수 있습니다.However, you can use a memory-optimized table variable to achieve a join outcome over multiple statements. 두 코드 샘플은 다음과 같습니다.Two code samples follow:

  • DELETE...JOIN... 네이티브 프로시저에서 실행하고 싶지만 불가능합니다.DELETE...JOIN... we want to run in a native proc, but cannot.
  • 조인 삭제를 달성하는 Transact-SQL 문의 해결 방법 집합.A work-around set of Transact-SQL statements that achieves the delete join.

시나리오: TabProjectEmployee 테이블에 두 열 ProjectId 및 EmployeeId의 고유 키가 있습니다.Scenario: The table TabProjectEmployee has a unique key of two columns: ProjectId and EmployeeId. 각 행은 활성 프로젝트에 대한 직원 할당을 나타냅니다.Each row indicates the assignment of an employee to an active project. 직원이 퇴사할 경우 TabProjectEmployee 테이블에서 직원을 삭제해야 합니다.When an Employee leaves the company, the employee must be deleted from the TabProjectEmployee table.

잘못된 T-SQL, DELETE...JOINInvalid T-SQL, DELETE...JOIN

네이티브 프로시저는 다음과 같은 DELETE...JOIN을 포함할 수 없습니다.A native proc cannot have a DELETE...JOIN such as the following.

DELETE pe
    FROM
             TabProjectEmployee   AS pe
        JOIN TabEmployee          AS e

            ON pe.EmployeeId = e.EmployeeId
    WHERE
            e.EmployeeStatus = 'Left-the-Company'
;

유효한 해결 방법, 수동 DELETE...JOINValid work-around, manual delete...join

다음은 두 부분으로 된 해결 방법 코드 샘플입니다.Next is the work-around code sample, in two parts:

  1. CREATE TYPE은 이 형식이 처음 실제 테이블 변수에서 사용되기 수일 전에 한 번 실행됩니다.The CREATE TYPE is executed one time, days before the type is first used by any actual table variable.

  2. 비즈니스 프로세스에서 만들어진 형식을 사용합니다.The business process uses the created type. 만들어진 테이블 형식의 테이블 변수를 선언하여 시작합니다.It begins by declaring a table variable of the created table type.


CREATE TYPE dbo.type_TableVar_EmployeeId
    AS TABLE  
    (
        EmployeeId   bigint   NOT NULL
    );

다음으로, 테이블 형식 만들기를 사용합니다.Next, use the create table type.

DECLARE @MyTableVarMo  dbo.type_TableVar_EmployeeId  

INSERT INTO @MyTableVarMo (EmployeeId)
    SELECT
            e.EmployeeId
        FROM
                 TabProjectEmployee  AS pe
            JOIN TabEmployee         AS e  ON e.EmployeeId = pe.EmployeeId
        WHERE
            e.EmployeeStatus = 'Left-the-Company'
;

DECLARE @EmployeeId   bigint;

WHILE (1=1)
BEGIN
    SET @EmployeeId = NULL;

    SELECT TOP 1 @EmployeeId = v.EmployeeId
        FROM @MyTableVarMo  AS v;

    IF (NULL = @Employeed) BREAK;

    DELETE TabProjectEmployee
        WHERE EmployeeId = @EmployeeId;

    DELETE @MyTableVarMo
        WHERE EmployeeId = @EmployeeId;
END;

E.4 네이티브 프로시저에 대한 쿼리 계획 제한 사항E.4 Query plan limitations for native procs

일부 쿼리 계획 유형은 네이티브 프로시저에 사용할 수 없습니다.Some types of query plans are not available for native procs. 많은 세부 정보는 다음에 설명되어 있습니다.Many details are discussed in:

네이티브 프로시저에서는 병렬 처리 불가No parallel processing in a native proc

병렬 처리는 네이티브 프로시저에 대한 쿼리 계획의 일부가 될 수 없습니다.Parallel processing cannot be a part of any query plan for a native proc. 네이티브 프로시저는 항상 단일 스레드입니다.Native procs are always single-threaded.

조인 유형Join types

해시 조인도 병합 조인도 네이티브 프로시저에 대한 쿼리 계획의 일부가 될 수 없습니다.Neither a hash join nor a merge join can be a part of any query plan for a native proc. 중첩 루프 조인이 사용됩니다.Nested loop joins are used.

해시 집계 없음No hash aggregation

네이티브 프로시저에 대한 쿼리 계획에 집계 단계가 필요한 경우 스트림 집계만 사용할 수 있습니다.When the query plan for a native proc requires an aggregation phase, only stream aggregation is available. 네이티브 프로시저에 대한 쿼리 계획에서는 해시 집계가 지원되지 않습니다.Hash aggregation is not supported in a query plan for a native proc.

  • 많은 수의 행에서 데이터를 집계해야 하는 경우 해시 집계가 낫습니다.Hash aggregation is better when data from a large number of rows must aggregated.

6.F. 응용 프로그램 디자인: 트랜잭션 및 재시도 논리Application design: Transactions and retry logic

메모리 액세스에 최적화된 테이블과 관련된 트랜잭션은 같은 테이블과 관련된 다른 트랜잭션에 종속될 수 있습니다.A transaction involving a memory-optimized table can become dependent on another transaction which involves the same table. 종속 트랜잭션 수가 허용된 최대값을 초과하면 모든 종속 트랜잭션이 실패합니다.If the count of dependent transactions reaches exceeds the allowed maximum, all the dependent transactions fail.

SQL Server 2016에서:In SQL Server 2016:

  • 종속 트랜잭션 수의 허용된 최대값은 8입니다.The allowed maximum is 8 dependent transactions. 8은 지정된 트랜잭션이 종속될 수 있는 트랜잭션의 제한이기도 합니다.8 is also the limit of transactions that any given transaction can be dependent on.
  • 오류 번호는 41839입니다.The error number is 41839. (SQL Server 2014에서 오류 번호는 41301입니다.)(In SQL Server 2014 the error number is 41301.)

스크립트에 재시도 논리 를 추가하여 Transact-SQL 스크립트를 가능한 트랜잭션 오류에 대해 더 강력하게 만들 수 있습니다.You can make your Transact-SQL scripts more robust against a possible transaction error by adding retry logic to your scripts. 재시도 논리는 UPDATE 및 DELETE 호출이 빈번하거나 다른 테이블의 외래 키가 메모리 액세스에 최적화된 테이블을 참조하는 경우 더 유용할 수 있습니다.Retry logic is more likely to help when UPDATE and DELETE calls are frequent, or if the memory-optimized table is referenced by a foreign key in another table. 자세한 내용은 다음을 참조하세요.For details, see: