메모리 최적화를 사용한 더 빠른 임시 테이블 및 테이블 변수Faster temp table and table variable by using memory optimization

이 항목 적용 대상: 예SQL Server예Azure SQL 데이터베이스없습니다Azure SQL 데이터 웨어하우스 없습니다 병렬 데이터 웨어하우스THIS TOPIC APPLIES TO: yesSQL ServeryesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

임시 테이블, 테이블 변수 또는 테이블 반환 매개 변수를 사용하는 경우 메모리 최적화 테이블 및 테이블 변수를 활용하도록 변환하여 성능을 향상시키는 것이 좋습니다.If you use temporary tables, table variables, or table-valued parameters, consider conversions of them to leverage memory-optimized tables and table variables to improve performance. 코드는 일반적으로 최소로 변경됩니다.The code changes are usually minimal.

이 문서에서는 다음에 대해 설명합니다.This article describes:

  • 메모리 내로 변환을 위한 시나리오Scenarios which argue in favor of conversion to In-Memory.
  • 메모리 내로 변환의 기술 구현 단계Technical steps for implementing the conversions to In-Memory.
  • 메모리 내로 변환하기 전의 필수 구성 요소Prerequisites before conversion to In-Memory.
  • 메모리 액세스에 최적화된 성능 이점을 강조하는 코드 샘플A code sample that highlights the performance benefits of memory-optimization

1.A. 메모리 최적화 테이블 변수 기본 사항Basics of memory-optimized table variables

메모리 최적화 테이블 변수는 메모리 최적화 테이블에서 사용하는 동일한 메모리 최적화 알고리즘 및 데이터 구조를 사용하여 훌륭한 효율성을 제공합니다.A memory-optimized table variable provides great efficiency by using the same memory-optimized algorithm and data structures that are used by memory-optimized tables. 테이블 변수가 고유하게 컴파일된 모듈 내에서 액세스될 때 효율성은 최대가 됩니다.The efficiency is maximized when the table variable is accessed from within a natively compiled module.

메모리 최적화 테이블 변수:A memory-optimized table variable:

  • 메모리에만 저장되고 디스크에 구성 요소가 없습니다.Is stored only in memory, and has no component on disk.
  • IO 작업이 관여되지 않습니다.Involves no IO activity.
  • tempdb 사용 또는 경합이 관여되지 않습니다.Involves no tempdb utilization or contention.
  • 저장 프로시저에 TVP(테이블 반환 매개 변수)로 전달될 수 있습니다.Can be passed into a stored proc as a table-valued parameter (TVP).
  • 하나 이상의 인덱스(해시 또는 비클러스터형)가 있어야 합니다.Must have at least one index, either hash or nonclustered.
    • 해시 인덱스의 경우 버킷 수는 예상 고유 인덱스 키 수의 1-2배가 되어야 이상적이지만 버킷 수를 최대 10배까지 고려하는 것이 좋습니다.For a hash index, the bucket count should ideally be 1-2 times the number of expected unique index keys, but overestimating bucket count is usually fine (up to 10X). 자세한 내용은 메모리 액세스에 최적화된 테이블의 인덱스를 참조하세요.For details see Indexes for Memory-Optimized Tables.

개체 유형Object types

메모리 내 OLTP는 메모리 액세스 최적화 임시 테이블 및 테이블 변수에 사용할 수 있는 다음과 같은 개체를 제공합니다.In-Memory OLTP provides the following objects that can be used for memory-optimizing temp tables and table variables:

  • 메모리 액세스에 최적화된 테이블Memory-optimized tables
    • Durability = SCHEMA_ONLYDurability = SCHEMA_ONLY
  • 메모리 액세스에 최적화된 테이블 변수Memory-optimized table variables
    • 인라인 대신 두 단계로 선언해야 합니다.Must be declared in two steps (rather than inline):
      • CREATE TYPE my_type AS TABLE ...; 그런 다음CREATE TYPE my_type AS TABLE ...; , then
      • DECLARE @mytablevariable my_type;를 참조하세요.DECLARE @mytablevariable my_type;.

2.B. 시나리오: 전역 tempdb ##table 바꾸기Scenario: Replace global tempdb ##table

메모리 최적화 SCHEMA_ONLY 테이블이 포함된 전역 임시 테이블을 교체하는 작업은 매우 간단합니다.Replacing a global temporary table with a memory-optimized SCHEMA_ONLY table is fairly straightforward. 런타임 시가 아니라 배포 시 테이블을 만든다는 것이 가장 큰 차이점입니다.The biggest change is to create the table at deployment time, not at runtime. 컴파일 시간 최적화로 인해 메모리 최적화 테이블을 만드는 시간은 기존의 테이블을 만드는 것보다 오래 걸립니다.Creation of memory-optimized tables takes longer than creation of traditional tables, due to the compile-time optimizations. 온라인 워크로드의 일부로 메모리 최적화 테이블을 만들고 삭제하는 작업은 워크로드의 성능뿐만 아니라 AlwaysOn 보조 데이터베이스와 데이터베이스 복구에 대한 다시 실행 성능에도 영향을 미칩니다.Creating and dropping memory-optimized tables as part of the online workload would impact the performance of the workload, as well as the performance of redo on AlwaysOn secondaries and database recovery.

다음과 같은 전역 임시 테이블이 있다고 가정합니다.Suppose you have the following global temporary table.

CREATE TABLE ##tempGlobalB  
(  
    Column1   INT   NOT NULL ,  
    Column2   NVARCHAR(4000)  
);  

전역 임시 테이블을 다음과 같이 DURABILITY = SCHEMA_ONLY가 선언된 메모리 최적화 테이블로 바꾸는 것이 좋습니다.Consider replacing the global temporary table with the following memory-optimized table that has DURABILITY = SCHEMA_ONLY.

CREATE TABLE dbo.soGlobalB  
(  
    Column1   INT   NOT NULL   INDEX ix1 NONCLUSTERED,  
    Column2   NVARCHAR(4000)  
)  
    WITH  
        (MEMORY_OPTIMIZED = ON,  
        DURABILITY        = SCHEMA_ONLY);  

B.1 단계B.1 Steps

전역 임시 테이블에서 SCHEMA_ONLY로 변환하는 단계는 다음과 같습니다.The conversion from global temporary to SCHEMA_ONLY is the following steps:

  1. 기존의 모든 디스크상 테이블에서처럼 dbo.soGlobalB 테이블을 한 번 만듭니다.Create the dbo.soGlobalB table, one time, just as you would any traditional on-disk table.
  2. TRANSACT-SQL에서 ##tempGlobalB 테이블의 생성을 제거합니다.From your Transact-SQL, remove the create of the ##tempGlobalB table. 테이블을 만들면 제공되는 컴파일 오버헤드를 방지하기 위해 런타임 시가 아닌 배포 시 메모리 최적화 테이블을 만드는 것이 중요합니다.It is important to create the memory-optimized table at deployment time, not at runtime, to avoid the compilation overhead that comes with table creation.
  3. T-SQL에서 ##tempGlobalB의 모든 멘션을 dbo.soGlobalB로 바꿉니다.In your T-SQL, replace all mentions of ##tempGlobalB with dbo.soGlobalB.

3.C. 시나리오: 세션 tempdb #table 바꾸기Scenario: Replace session tempdb #table

세션 임시 테이블을 바꾸기 위한 준비 작업에는 이전의 전역 임시 테이블 시나리오보다 더 많은 T-SQL이 포함됩니다.The preparations for replacing a session temporary table involve more T-SQL than for the earlier global temporary table scenario. 다행히 변환을 수행하는 데에는 추가 T-SQL이 필요하지 않습니다.Happily the extra T-SQL does not mean any more effort is needed to accomplish the conversion.

전역 임시 테이블 시나리오에서는 컴파일 오버헤드를 방지하기 위해 런타임 시가 아닌 배포 시 테이블을 만든다는 점이 가장 큰 변화입니다.As with the global temp table scenario, the biggest change is to create the table at deployment time, not runtime, to avoid the compilation overhead.

다음과 같은 세션 임시 테이블이 있다고 가정합니다.Suppose you have the following session temporary table.

CREATE TABLE #tempSessionC  
(  
    Column1   INT   NOT NULL ,  
    Column2   NVARCHAR(4000)  
);  

첫째, 다음과 같이 테이블 반환 함수를 만들어 @@spid로 필터링합니다.First, create the following table-value function to filter on @@spid. 함수는 세션 임시 테이블에서 변환하는 모든 SCHEMA_ONLY 테이블에서 사용할 수 있습니다.The function will be usable by all SCHEMA_ONLY tables that you convert from session temporary tables.

CREATE FUNCTION dbo.fn_SpidFilter(@SpidFilter smallint)  
    RETURNS TABLE  
    WITH SCHEMABINDING , NATIVE_COMPILATION  
AS  
    RETURN  
        SELECT 1 AS fn_SpidFilter  
            WHERE @SpidFilter = @@spid;  

둘째, SCHEMA_ONLY 테이블 및 테이블의 보안 정책을 만듭니다.Second, create the SCHEMA_ONLY table, plus a security policy on the table.

메모리 최적화 각 테이블에는 하나 이상의 인덱스가 있어야 합니다.Note that each memory-optimized table must have at least one index.

  • 테이블 dbo.soSessionC의 경우 적절한 BUCKET_COUNT를 계산하는 경우 해시 인덱스가 더 나을 수 있습니다.For table dbo.soSessionC a HASH index might be better, if we calculate the appropriate BUCKET_COUNT. 하지만 이 예제에서는 비클러스터형 인덱스로 간소화합니다.But for this sample we simplify to a NONCLUSTERED index.
<span data-ttu-id="5a1bc-156">CREATE TABLE dbo.soSessionC</span><span class="sxs-lookup"><span data-stu-id="5a1bc-156">CREATE TABLE dbo.soSessionC</span></span>  
<span data-ttu-id="5a1bc-157">(</span><span class="sxs-lookup"><span data-stu-id="5a1bc-157">(</span></span>  
    <span data-ttu-id="5a1bc-158">Column1     INT         NOT NULL,</span><span class="sxs-lookup"><span data-stu-id="5a1bc-158">Column1     INT         NOT NULL,</span></span>  
    <span data-ttu-id="5a1bc-159">Column2     NVARCHAR(4000)  NULL,</span><span class="sxs-lookup"><span data-stu-id="5a1bc-159">Column2     NVARCHAR(4000)  NULL,</span></span>  

    SpidFilter  SMALLINT    NOT NULL   DEFAULT (@@spid),  

    INDEX ix_SpidFiler NONCLUSTERED (SpidFilter),  
    --INDEX ix_SpidFilter HASH  
    --    (SpidFilter) WITH (BUCKET_COUNT = 64),  

    CONSTRAINT CHK_soSessionC_SpidFilter  
        CHECK ( SpidFilter = @@spid ),  
<span data-ttu-id="5a1bc-160">).</span><span class="sxs-lookup"><span data-stu-id="5a1bc-160">)</span></span>  
    <span data-ttu-id="5a1bc-161">의 모든 멘션을</span><span class="sxs-lookup"><span data-stu-id="5a1bc-161">WITH</span></span>  
        <span data-ttu-id="5a1bc-162">(MEMORY_OPTIMIZED = ON,</span><span class="sxs-lookup"><span data-stu-id="5a1bc-162">(MEMORY_OPTIMIZED = ON,</span></span>  
         <span data-ttu-id="5a1bc-163">DURABILITY = SCHEMA_ONLY);</span><span class="sxs-lookup"><span data-stu-id="5a1bc-163">DURABILITY = SCHEMA_ONLY);</span></span>  
<span data-ttu-id="5a1bc-164">go</span><span class="sxs-lookup"><span data-stu-id="5a1bc-164">go</span></span>  


<span data-ttu-id="5a1bc-165">CREATE SECURITY POLICY dbo.soSessionC_SpidFilter_Policy</span><span class="sxs-lookup"><span data-stu-id="5a1bc-165">CREATE SECURITY POLICY dbo.soSessionC_SpidFilter_Policy</span></span>  
    <span data-ttu-id="5a1bc-166">ADD FILTER PREDICATE dbo.fn_SpidFilter(SpidFilter)</span><span class="sxs-lookup"><span data-stu-id="5a1bc-166">ADD FILTER PREDICATE dbo.fn_SpidFilter(SpidFilter)</span></span>  
    <span data-ttu-id="5a1bc-167">ON dbo.soSessionC</span><span class="sxs-lookup"><span data-stu-id="5a1bc-167">ON dbo.soSessionC</span></span>  
    <span data-ttu-id="5a1bc-168">WITH (STATE = ON);</span><span class="sxs-lookup"><span data-stu-id="5a1bc-168">WITH (STATE = ON);</span></span>  
<span data-ttu-id="5a1bc-169">go</span><span class="sxs-lookup"><span data-stu-id="5a1bc-169">go</span></span>  

셋째, 일반 T-SQL 코드에서 다음을 수행합니다.Third, in your general T-SQL code:

  1. 새 메모리 최적화 테이블에 대한 Transact-SQL 문에서 임시 테이블에 대한 모든 참조를 변경합니다.Change all references to the temp table in your Transact-SQL statements to the new memory-optimized table:
    • 이전 이름: #tempSessionCOld: #tempSessionC
    • 새 이름: dbo.soSessionCNew: dbo.soSessionC
  2. 코드에서 CREATE TABLE #tempSessionC 문을 DELETE FROM dbo.soSessionC로 바꿔 동일한 session_id로 이전 세션에서 삽입한 테이블 콘텐츠에 세션이 노출되지 않도록 합니다.Replace the CREATE TABLE #tempSessionC statements in your code with DELETE FROM dbo.soSessionC, to ensure a session is not exposed to table contents inserted by a previous session with the same session_id. 테이블을 만들면 제공되는 컴파일 오버헤드를 방지하기 위해 런타임 시가 아닌 배포 시 메모리 최적화 테이블을 만드는 것이 중요합니다.It is important to create the memory-optimized table at deployment time, not at runtime, to avoid the compilation overhead that comes with table creation.
  3. 코드에서 DROP TABLE #tempSessionC 문을 제거합니다. 메모리 크기가 잠재적 고려 사항인 경우 필요에 따라 DELETE FROM dbo.soSessionC 문을 삽입할 수 있습니다.Remove the DROP TABLE #tempSessionC statements from your code – optionally you can insert a DELETE FROM dbo.soSessionC statement, in case memory size is a potential concern

4.D. 시나리오: 테이블 변수가 MEMORY_OPTIMIZED=ON일 수 있습니다.Scenario: Table variable can be MEMORY_OPTIMIZED=ON

기존의 테이블 변수는 tempdb 데이터베이스에서 테이블을 나타냅니다.A traditional table variable represents a table in the tempdb database. 훨씬 빠른 성능을 위해 테이블 변수를 메모리 액세스에 최적화할 수 있습니다.For much faster performance you can memory-optimize your table variable.

기존의 테이블 변수에 대한 T-SQL은 다음과 같습니다.Here is the T-SQL for a traditional table variable. 해당 범위는 일괄 처리 또는 세션이 끝날 때 종료됩니다.Its scope ends when either the batch or the session ends.

DECLARE @tvTableD TABLE  
    ( Column1   INT   NOT NULL ,  
      Column2   CHAR(10) );  

D.1 명시적으로 인라인 변환D.1 Convert inline to explicit

위의 구문은 테이블 변수가 인라인으로 만들어졌습니다.The preceding syntax is said to create the table variable inline. 인라인 구문은 메모리 액세스에 최적화를 지원하지 않습니다.The inline syntax does not support memory-optimization. 그러면 인라인 구문을 TYPE의 명시적 구문으로 변환해 보겠습니다.So let us convert the inline syntax to the explicit syntax for the TYPE.

범위: 첫 번째 go로 구분된 일괄 처리에 의해 만들어진 TYPE 정의는 서버를 종료하고 다시 시작한 후에도 유지됩니다.Scope: The TYPE definition created by the first go-delimited batch persists even after the server is shutdown and restarted. 하지만 첫 번째 go 구분 기호 이후 선언된 테이블 @tvTableC는 다음 go에 도달하고 일괄 처리가 종료될 때까지만 유지됩니다.But after the first go delimiter, the declared table @tvTableC persists only until the next go is reached and the batch ends.

CREATE TYPE dbo.typeTableD  
    AS TABLE  
    (  
        Column1  INT   NOT NULL ,  
        Column2  CHAR(10)  
    );  
go  

SET NoCount ON;  
DECLARE @tvTableD dbo.typeTableD  
;  
INSERT INTO @tvTableD (Column1) values (1), (2)  
;  
SELECT * from @tvTableD;  
go  

D.2 메모리 최적화되도록 디스크상 명시적 변환D.2 Convert explicit on-disk to memory-optimized

메모리 최적화 테이블 변수는 tempdb에 상주하지 않습니다.A memory-optimized table variable does not reside in tempdb. 메모리 액세스 최적화는 종종 속도가 10배 이상 빨라지는 결과를 낳습니다.Memory-optimization results in speed increases that are often 10 times faster or more.

메모리 최적화로 변환하는 작업은 한 단계로 구현됩니다.The conversion to memory-optimized is achieved in only one step. 다음과 같이 추가하여 명시적 TYPE 만들기를 개선합니다.Enhance the explicit TYPE creation to be the following, which adds:

  • 인덱스.An index. 다시 말하지만 메모리 최적화 각 테이블에는 하나 이상의 인덱스가 있어야 합니다.Again, each memory-optimized table must have at least one index.
  • MEMORY_OPTIMIZED = ON.MEMORY_OPTIMIZED = ON.
<span data-ttu-id="5a1bc-197">CREATE TYPE dbo.typeTableD</span><span class="sxs-lookup"><span data-stu-id="5a1bc-197">CREATE TYPE dbo.typeTableD</span></span>  
    <span data-ttu-id="5a1bc-198">AS TABLE</span><span class="sxs-lookup"><span data-stu-id="5a1bc-198">AS TABLE</span></span>  
    <span data-ttu-id="5a1bc-199">(</span><span class="sxs-lookup"><span data-stu-id="5a1bc-199">(</span></span>  
        <span data-ttu-id="5a1bc-200">Column1  INT   NOT NULL   INDEX ix1,</span><span class="sxs-lookup"><span data-stu-id="5a1bc-200">Column1  INT   NOT NULL   INDEX ix1,</span></span>  
        <span data-ttu-id="5a1bc-201">Column2  CHAR(10)</span><span class="sxs-lookup"><span data-stu-id="5a1bc-201">Column2  CHAR(10)</span></span>  
    <span data-ttu-id="5a1bc-202">).</span><span class="sxs-lookup"><span data-stu-id="5a1bc-202">)</span></span>  
    <span data-ttu-id="5a1bc-203">의 모든 멘션을</span><span class="sxs-lookup"><span data-stu-id="5a1bc-203">WITH</span></span>  
        <span data-ttu-id="5a1bc-204">(MEMORY_OPTIMIZED = ON);</span><span class="sxs-lookup"><span data-stu-id="5a1bc-204">(MEMORY_OPTIMIZED = ON);</span></span>  

완료되었습니다.Done.

5.E. SQL Server에 대한 필수 구성 요소 FILEGROUPPrerequisite FILEGROUP for SQL Server

Microsoft SQL Server에서 메모리 최적화 기능을 사용하려면 데이터베이스에 MEMORY_OPTIMIZED_DATA로 선언된 FILEGROUP이 있어야 합니다.On Microsoft SQL Server, to use memory-optimized features, your database must have a FILEGROUP that is declared with MEMORY_OPTIMIZED_DATA.

  • Azure SQL 데이터베이스에서는 이 FILEGROUP을 만들지 않아도 됩니다.Azure SQL Database does not require creating this FILEGROUP.

필수 구성 요소: FILEGROUP에 대한 다음 TRANSACT-SQL 코드는 이 문서의 뒷부분에 나오는 섹션에서 긴 T-SQL 코드 샘플에 대한 필수 구성 요소입니다.Prerequisite: The following Transact-SQL code for a FILEGROUP is a prerequisite for the long T-SQL code samples in later sections of this article.

  1. SSMS.exe 또는 T-SQL을 전송할 수 있는 다른 도구를 사용해야 합니다.You must use SSMS.exe or another tool that can submit T-SQL.
  2. SSMS에 예제 FILEGROUP T-SQL 코드를 붙여넣습니다.Paste the sample FILEGROUP T-SQL code into SSMS.
  3. T-SQL을 편집하여 원하는 대로 해당 특정 이름 및 디렉터리 경로를 변경합니다.Edit the T-SQL to change its specific names and directory paths to your liking.
    • 마지막 디렉터리를 제외하고 FILENAME 값의 모든 디렉터리는 기존의 디렉터리여야 합니다.All directories in the FILENAME value must preexist, except the final directory must not preexist.
  4. 편집된 T-SQL을 실행합니다.Run your edited T-SQL.
    • 다음 하위 섹션에서 반복해서 조정하고 속도 비교 T-SQL을 다시 실행해도 FILEGROUP T-SQL은 한 번만 실행하면 됩니다.There is no need to run the FILEGROUP T-SQL more than one time, even if you repeatedly adjust and rerun the speed comparison T-SQL in the next subsection.
<span data-ttu-id="5a1bc-217">ALTER DATABASE InMemTest2</span><span class="sxs-lookup"><span data-stu-id="5a1bc-217">ALTER DATABASE InMemTest2</span></span>  
    <span data-ttu-id="5a1bc-218">ADD FILEGROUP FgMemOptim3</span><span class="sxs-lookup"><span data-stu-id="5a1bc-218">ADD FILEGROUP FgMemOptim3</span></span>  
        <span data-ttu-id="5a1bc-219">CONTAINS MEMORY_OPTIMIZED_DATA;</span><span class="sxs-lookup"><span data-stu-id="5a1bc-219">CONTAINS MEMORY_OPTIMIZED_DATA;</span></span>  
<span data-ttu-id="5a1bc-220">go</span><span class="sxs-lookup"><span data-stu-id="5a1bc-220">go</span></span>  
<span data-ttu-id="5a1bc-221">ALTER DATABASE InMemTest2</span><span class="sxs-lookup"><span data-stu-id="5a1bc-221">ALTER DATABASE InMemTest2</span></span>  
    <span data-ttu-id="5a1bc-222">ADD FILE</span><span class="sxs-lookup"><span data-stu-id="5a1bc-222">ADD FILE</span></span>  
    <span data-ttu-id="5a1bc-223">(</span><span class="sxs-lookup"><span data-stu-id="5a1bc-223">(</span></span>  
        <span data-ttu-id="5a1bc-224">NAME = N'FileMemOptim3a',</span><span class="sxs-lookup"><span data-stu-id="5a1bc-224">NAME = N'FileMemOptim3a',</span></span>  
        <span data-ttu-id="5a1bc-225">FILENAME = N'C:\DATA\FileMemOptim3a'</span><span class="sxs-lookup"><span data-stu-id="5a1bc-225">FILENAME = N'C:\DATA\FileMemOptim3a'</span></span>  
                 <span data-ttu-id="5a1bc-226">--  C:\DATA\    preexisted.</span><span class="sxs-lookup"><span data-stu-id="5a1bc-226">--  C:\DATA\    preexisted.</span></span>  
    <span data-ttu-id="5a1bc-227">).</span><span class="sxs-lookup"><span data-stu-id="5a1bc-227">)</span></span>  
    <span data-ttu-id="5a1bc-228">TO FILEGROUP FgMemOptim3;</span><span class="sxs-lookup"><span data-stu-id="5a1bc-228">TO FILEGROUP FgMemOptim3;</span></span>  
<span data-ttu-id="5a1bc-229">go</span><span class="sxs-lookup"><span data-stu-id="5a1bc-229">go</span></span>  

다음 스크립트는 파일 그룹을 만들고 권장되는 데이터베이스 설정을 구성합니다. enable-in-memory-oltp.sqlThe following script creates the filegroup for you and configures recommended database settings: enable-in-memory-oltp.sql

FILE 및 FILEGROUP의 ALTER DATABASE ... ADD 에 대한 자세한 내용은 다음을 참조하세요.For more information about ALTER DATABASE ... ADD for FILE and FILEGROUP, see:

6.F. 속도 개선을 보여 주는 빠른 테스트Quick test to prove speed improvement

이 섹션에서는 메모리 최적화 테이블 변수를 사용하여 INSERT-DELETE에 대한 속도 향상을 테스트하고 비교하는 데 실행할 수 있는 TRANSACT-SQL 코드를 제공합니다.This section provides Transact-SQL code that you can run to test and compare the speed gain for INSERT-DELETE from using a memory-optimized table variable. 코드는 처음 절반에서 테이블 형식이 메모리 최적화되었다는 점을 제외하고는 거의 동일한 두 부분으로 구성됩니다.The code is composed of two halves that are nearly the same, except in the first half the table type is memory-optimized.

비교 테스트는 약 7초간 지속됩니다.The comparison test lasts about 7 seconds. 예제를 실행하려면To run the sample:

  1. 필수 구성 요소: 이전 섹션에서 FILEGROUP T-SQL을 이미 실행했어야 합니다.Prerequisite: You must already have run the FILEGROUP T-SQL from the previous section.
  2. 다음 T-SQL INSERT-DELETE 스크립트를 실행합니다.Run the following T-SQL INSERT-DELETE script.
    • T-SQL을 5001번 다시 전송하는 'GO 5001' 문이 있습니다.Notice the 'GO 5001' statement, which resubmits the T-SQL 5001 times. 횟수를 조정하고 다시 실행할 수 있습니다.You can adjust the number and rerun.

Azure SQL 데이터베이스에서 스크립트를 실행하는 경우 동일한 지역의 VM에서 실행해야 합니다.When running the script in an Azure SQL Database, make sure to run from a VM in the same region.

PRINT ' ';  
PRINT '---- Next, memory-optimized, faster. ----';  

DROP TYPE IF EXISTS dbo.typeTableC_mem;  
go  
CREATE TYPE dbo.typeTableC_mem  -- !!  Memory-optimized.  
     AS TABLE  
     (  
          Column1  INT NOT NULL INDEX ix1,  
          Column2  CHAR(10)  
     )  
     WITH  
          (MEMORY_OPTIMIZED = ON);  
go  
DECLARE @dateString_Begin nvarchar(64) =  
    Convert(nvarchar(64), GetUtcDate(), 121);  
PRINT Concat(@dateString_Begin, '  = Begin time, _mem.');  
go  
SET NoCount ON;  
DECLARE @tvTableC dbo.typeTableC_mem;  -- !!  

INSERT INTO @tvTableC (Column1) values (1), (2);  
INSERT INTO @tvTableC (Column1) values (3), (4);  
DELETE @tvTableC;  

GO 5001  

DECLARE @dateString_End nvarchar(64) =  
    Convert(nvarchar(64), GetUtcDate(), 121);  
PRINT Concat(@dateString_End, '  = End time, _mem.');  
go  
DROP TYPE IF EXISTS dbo.typeTableC_mem;  
go  

---- End memory-optimized.  
-------------------------------------------------  
---- Start traditional on-disk.  

PRINT ' ';  
PRINT '---- Next, tempdb based, slower. ----';  

DROP TYPE IF EXISTS dbo.typeTableC_tempdb;  
go  
CREATE TYPE dbo.typeTableC_tempdb  -- !!  Traditional tempdb.  
    AS TABLE  
    (  
        Column1  INT NOT NULL ,  
        Column2  CHAR(10)  
    );  
go  
DECLARE @dateString_Begin nvarchar(64) =  
    Convert(nvarchar(64), GetUtcDate(), 121);  
PRINT Concat(@dateString_Begin, '  = Begin time, _tempdb.');  
go  
SET NoCount ON;  
DECLARE @tvTableC dbo.typeTableC_tempdb;  -- !!  

INSERT INTO @tvTableC (Column1) values (1), (2);  
INSERT INTO @tvTableC (Column1) values (3), (4);  
DELETE @tvTableC;  

GO 5001  

DECLARE @dateString_End nvarchar(64) =  
    Convert(nvarchar(64), GetUtcDate(), 121);  
PRINT Concat(@dateString_End, '  = End time, _tempdb.');  
go  
DROP TYPE IF EXISTS dbo.typeTableC_tempdb;  
go  
----  

PRINT '---- Tests done. ----';  

go  

/*** Actual output, SQL Server 2016:  

---- Next, memory-optimized, faster. ----  
2016-04-20 00:26:58.033  = Begin time, _mem.  
Beginning execution loop  
Batch execution completed 5001 times.  
2016-04-20 00:26:58.733  = End time, _mem.  

---- Next, tempdb based, slower. ----  
2016-04-20 00:26:58.750  = Begin time, _tempdb.  
Beginning execution loop  
Batch execution completed 5001 times.  
2016-04-20 00:27:05.440  = End time, _tempdb.  
---- Tests done. ----  
***/  

7.G. 활성 메모리 사용량 예측Predict active memory consumption

다음 리소스를 사용하면 메모리 최적화 테이블의 활성 메모리 요구량을 예측할 수 있습니다.You can learn to predict the active memory needs of your memory-optimized tables with the following resources:

큰 테이블 변수의 경우 비클러스터형 인덱스는 메모리 최적화 테이블보다 더 많은 메모리를 사용합니다.For larger table variables, nonclustered indexes use more memory than they do for memory-optimized tables. 행 개수 및 인덱스 키가 클수록 차이가 증가합니다.The larger the row count and the index key, the more the difference increases.

메모리 최적화 테이블 변수가 액세스당 하나의 정확한 키 값에만 액세스하는 경우 비클러스터형 인덱스보다 해시 인덱스가 더 적합할 수 있습니다.If the memory-optimized table variable is accessed only with one exact key value per access, a hash index might be a better choice than a nonclustered index. 그러나 적절한 BUCKET_COUNT를 예측할 수 없는 경우 비클러스터형 인덱스가 차선책입니다.However, if you cannot estimate the appropriate BUCKET_COUNT, a NONCLUSTERED index is a good second choice.

8.H. 참고 항목See also