통계Statistics

쿼리 최적화 프로그램에서는 통계를 사용하여 쿼리 성능을 향상시키는 쿼리 계획을 만듭니다.The query optimizer uses statistics to create query plans that improve query performance. 대부분의 쿼리에서 쿼리 최적화 프로그램은 고품질의 쿼리 계획에 필요한 통계를 이미 생성하므로 경우에 따라서 최상의 결과를 위해 추가 통계를 만들거나 쿼리 설계를 수정해야 합니다.For most queries, the query optimizer already generates the necessary statistics for a high quality query plan; in a few cases, you need to create additional statistics or modify the query design for best results. 이 항목에서는 통계 개념에 대해 설명하고 쿼리 최적화 통계를 효율적으로 사용하기 위한 지침을 제공합니다.This topic discusses statistics concepts and provides guidelines for using query optimization statistics effectively.

구성 요소 및 개념 Components and Concepts

통계Statistics
쿼리 최적화 통계는 테이블이나 인덱싱된 뷰에서 하나 이상의 열에 있는 값의 분포에 대한 통계 정보를 포함하는 개체입니다.Statistics for query optimization are objects that contain statistical information about the distribution of values in one or more columns of a table or indexed view. 쿼리 최적화 프로그램은 이러한 통계를 사용하여 쿼리 결과에서 카디널리티또는 행 수를 계산합니다.The query optimizer uses these statistics to estimate the cardinality, or number of rows, in the query result. 쿼리 최적화 프로그램은 이러한 카디널리티 예상치 를 통해 고품질의 쿼리 계획을 만듭니다.These cardinality estimates enable the query optimizer to create a high-quality query plan. 예를 들어 쿼리 최적화 프로그램은 카디널리티 예상치를 사용하여 리소스를 많이 사용하는 index scan 연산자 대신 index seek 연산자를 선택할 수 있으며 이렇게 하면 쿼리 성능이 향상됩니다.For example, the query optimizer could use cardinality estimates to choose the index seek operator instead of the more resource-intensive index scan operator, and in doing so improve query performance.

각 통계 개체는 하나 이상의 테이블 열 목록에 대해 작성되며 첫 번째 열의 값 분포를 나타내는 히스토그램을 포함합니다.Each statistics object is created on a list of one or more table columns and includes a histogram displaying the distribution of values in the first column. 여러 열에 대한 통계 개체는 또한 열 사이의 값의 상관 관계에 대한 통계 정보도 저장합니다.Statistics objects on multiple columns also store statistical information about the correlation of values among the columns. 이러한 상관 관계 통계 또는 밀도는 열 값의 개별 행 수에서 생성됩니다.These correlation statistics, or densities, are derived from the number of distinct rows of column values. 통계 개체에 대한 자세한 내용은 DBCC SHOW_STATISTICS(Transact-SQL)를 참조하세요.For more information about statistics objects, see DBCC SHOW_STATISTICS (Transact-SQL).

필터링된 통계Filtered Statistics
필터링된 통계는 잘 정의된 데이터의 하위 집합에서 선택하는 쿼리에 대한 쿼리 성능을 높일 수 있습니다.Filtered statistics can improve query performance for queries that select from well-defined subsets of data. 또한 필터 조건자를 사용하여 통계에 포함되는 데이터의 하위 집합을 선택할 수 있습니다.Filtered statistics use a filter predicate to select the subset of data that is included in the statistics. 잘 디자인된 필터링된 통계는 전체 테이블 통계에 비해 쿼리 실행 계획을 향상시킬 수 있습니다.Well-designed filtered statistics can improve the query execution plan compared with full-table statistics. 필터 조건자에 대한 자세한 내용은 CREATE STATISTICS(Transact-SQL)를 참조하세요.For more information about the filter predicate, see CREATE STATISTICS (Transact-SQL). 필터링된 통계를 작성하는 시기에 대한 자세한 내용은 이 항목의 통계 작성 시기 섹션을 참조하십시오.For more information about when to create filtered statistics, see the When to Create Statistics section in this topic. 사례 연구를 보려면 SQLCAT 웹 사이트에서 분할된 테이블에서 필터링된 통계 사용블로그 항목을 참조하십시오.For a case study, see the blog entry, Using Filtered Statistics with Partitioned Tables, on the SQLCAT Web site.

통계 옵션Statistics Options
통계가 작성되고 업데이트되는 시기 및 방법에 영향을 주는 다음 세 가지 옵션을 설정할 수 있습니다.There are three options that you can set that affect when and how statistics are created and updated. 이러한 옵션은 데이터베이스 수준에서만 설정됩니다.These options are set at the database level only.

AUTO_CREATE_STATISTICS 옵션AUTO_CREATE_STATISTICS Option
자동 통계 작성 옵션 AUTO_CREATE_STATISTICS가 ON으로 설정된 경우 쿼리 최적화 프로그램은 필요에 따라 쿼리 조건자의 개별 열에 대한 통계를 작성하므로 쿼리 계획에 대한 카디널리티 예상치의 정확도가 높아집니다.When the automatic create statistics option, AUTO_CREATE_STATISTICS, is on, the query optimizer creates statistics on individual columns in the query predicate, as necessary, to improve cardinality estimates for the query plan. 이러한 단일 열 통계는 기존 통계 개체에 히스토그램이 없는 열에 대해 작성됩니다.These single-column statistics are created on columns that do not already have a histogram in an existing statistics object. AUTO_CREATE_STATISTICS 옵션에서는 인덱스에 대해 통계가 작성되는지 확인하지 않습니다.The AUTO_CREATE_STATISTICS option does not determine whether statistics get created for indexes. 이 옵션은 또한 필터링된 통계도 생성하지 않으며This option also does not generate filtered statistics. 전체 테이블에 대한 단일 열 통계에 엄격하게 적용됩니다.It applies strictly to single-column statistics for the full table.

쿼리 최적화 프로그램이 AUTO_CREATE_STATISTICS 옵션 사용 결과로 통계를 작성하면 통계 이름이 _WA로 시작합니다.When the query optimizer creates statistics as a result of using the AUTO_CREATE_STATISTICS option, the statistics name starts with _WA. 다음 쿼리를 사용하여 쿼리 최적화 프로그램이 쿼리 조건자 열에 대한 통계를 작성했는지 확인할 수 있습니다.You can use the following query to determine if the query optimizer has created statistics for a query predicate column.

SELECT OBJECT_NAME(s.object_id) AS object_name,  
    COL_NAME(sc.object_id, sc.column_id) AS column_name,  
    s.name AS statistics_name  
FROM sys.stats AS s JOIN sys.stats_columns AS sc  
    ON s.stats_id = sc.stats_id AND s.object_id = sc.object_id  
WHERE s.name like '_WA%'  
ORDER BY s.name;  

AUTO_UPDATE_STATISTICS 옵션AUTO_UPDATE_STATISTICS Option
자동 통계 업데이트 옵션 AUTO_UPDATE_STATISTICS가 ON으로 설정되면 쿼리 최적화 프로그램은 통계가 최신이 아닌 통계가 되는 시점을 확인한 다음 쿼리에서 사용될 때 이를 업데이트합니다.When the automatic update statistics option, AUTO_UPDATE_STATISTICS, is on, the query optimizer determines when statistics might be out-of-date and then updates them when they are used by a query. 삽입, 업데이트, 삭제 또는 병합 작업을 통해 테이블이나 인덱싱된 뷰의 데이터 분포가 변경되면 통계 내용이 더 이상 최신이 아니게 됩니다.Statistics become out-of-date after insert, update, delete, or merge operations change the data distribution in the table or indexed view. 쿼리 최적화 프로그램은 마지막 통계 업데이트 이후 데이터 수정 개수를 계산한 다음 이 수를 임계값과 비교하여 통계가 최신이 아니게 된 시점을 결정합니다.The query optimizer determines when statistics might be out-of-date by counting the number of data modifications since the last statistics update and comparing the number of modifications to a threshold. 임계값은 테이블 또는 인덱싱된 뷰의 행 수를 기준으로 합니다.The threshold is based on the number of rows in the table or indexed view.

  • SQL Server 2014 이하 버전에서는 변경된 행 비율에 따라 임계값을 사용합니다.SQL Server (2014 and earlier) uses a threshold based on the percent of rows changed. 테이블의 행 수에 관계없이 이러한 방식이 사용됩니다.This is regardless of the number of rows in the table.

  • SQL Server(2016 및 호환성 수준 130부터)는 테이블의 행 수에 따라 조정되는 임계값을 사용합니다.SQL Server (starting with 2016 and under the compatibility level 130) uses a threshold that adjusts according to the number of rows in the table. 이러한 변경으로 인해 큰 테이블의 통계 업데이트 빈도가 높아집니다.With this change, statistics on large tables will be updated more often.

    쿼리 최적화 프로그램은 쿼리를 컴파일하기 전과 캐시된 쿼리 계획을 실행하기 전에 최신이 아닌 통계가 있는지를 확인합니다.The query optimizer checks for out-of-date statistics before compiling a query and before executing a cached query plan. 쿼리 최적화 프로그램은 쿼리를 컴파일하기 전에 쿼리 조건자의 열, 테이블 및 인덱싱된 뷰를 사용하여 어떤 통계가 최신이 아닌지 결정합니다.Before compiling a query, the query optimizer uses the columns, tables, and indexed views in the query predicate to determine which statistics might be out-of-date. 데이터베이스 엔진Database Engine 에서는 캐시된 쿼리 계획을 실행하기 전에 쿼리 계획에서 최신 통계가 참조되는지 확인합니다.Before executing a cached query plan, the 데이터베이스 엔진Database Engine verifies that the query plan references up-to-date statistics.

    AUTO_UPDATE_STATISTICS 옵션은 인덱스에 대해 작성된 통계 개체, 쿼리 조건자의 단일 열 및 CREATE STATISTICS 문으로 작성된 통계에 적용됩니다.The AUTO_UPDATE_STATISTICS option applies to statistics objects created for indexes, single-columns in query predicates, and statistics created with the CREATE STATISTICS statement. 이 옵션은 또한 필터링된 통계에도 적용됩니다.This option also applies to filtered statistics.

    AUTO_UPDATE_STATISTICS_ASYNCAUTO_UPDATE_STATISTICS_ASYNC
    비동기 통계 업데이트 옵션인 AUTO_UPDATE_STATISTICS_ASYNC는 쿼리 최적화 프로그램이 동기 또는 비동기 통계 업데이트를 사용하는지를 결정합니다.The asynchronous statistics update option, AUTO_UPDATE_STATISTICS_ASYNC, determines whether the query optimizer uses synchronous or asynchronous statistics updates. 기본적으로 비동기 통계 업데이트 옵션은 OFF이며 쿼리 최적화 프로그램은 통계를 동기적으로 업데이트합니다.By default, the asynchronous statistics update option is off, and the query optimizer updates statistics synchronously. AUTO_UPDATE_STATISTICS_ASYNC 옵션은 인덱스에 대해 작성된 통계 개체, 쿼리 조건자의 단일 열 및 CREATE STATISTICS 문으로 작성된 통계에 적용됩니다.The AUTO_UPDATE_STATISTICS_ASYNC option applies to statistics objects created for indexes, single columns in query predicates, and statistics created with the CREATE STATISTICS statement.

    통계 업데이트는 동기(기본값) 또는 비동기일 수 있습니다.Statistics updates can be either synchronous (the default) or asynchronous. 동기 통계 업데이트의 경우 쿼리는 항상 최신 통계로 컴파일하고 실행합니다. 통계가 최신이 아닌 경우 쿼리를 컴파일하고 실행하기 전에 쿼리 최적화 프로그램에서 업데이트된 통계를 기다립니다.With synchronous statistics updates, queries always compile and execute with up-to-date statistics; When statistics are out-of-date, the query optimizer waits for updated statistics before compiling and executing the query. 비동기 통계 업데이트의 경우 쿼리는 기존 통계가 최신 통계가 아닌 경우에도 기존 통계로 컴파일합니다. 쿼리가 컴파일될 때 통계가 오래된 통계인 경우 쿼리 최적화 프로그램은 만족스럽지 못한 쿼리 계획을 선택할 수 있습니다.With asynchronous statistics updates, queries compile with existing statistics even if the existing statistics are out-of-date; The query optimizer could choose a suboptimal query plan if statistics are out-of-date when the query compiles. 비동기 업데이트가 완료된 이후 컴파일된 쿼리는 업데이트된 통계 사용의 이점을 얻을 수 있습니다.Queries that compile after the asynchronous updates have completed will benefit from using the updated statistics.

    테이블을 잘라내거나 상당 비율의 행에 대해 대량 업데이트를 수행하는 경우와 같이 데이터 분포를 변경하는 작업을 수행할 때는 동기 통계를 사용하는 것이 좋습니다.Consider using synchronous statistics when you perform operations that change the distribution of data, such as truncating a table or performing a bulk update of a large percentage of the rows. 작업을 완료한 후 통계를 업데이트하지 않은 경우 동기 통계를 사용하면 변경된 데이터에 대해 쿼리를 실행하기 전에 통계를 최신 상태로 유지할 수 있습니다.If you do not update the statistics after completing the operation, using synchronous statistics will ensure statistics are up-to-date before executing queries on the changed data.

    다음과 같은 시나리오에서 보다 예상 가능한 쿼리 응답 시간을 얻으려면 비동기 통계를 사용하십시오.Consider using asynchronous statistics to achieve more predictable query response times for the following scenarios:

  • 응용 프로그램에서 동일한 쿼리, 유사한 쿼리 또는 유사한 캐시된 쿼리 계획을 자주 실행하는 경우.Your application frequently executes the same query, similar queries, or similar cached query plans. 쿼리 최적화 프로그램은 최신 통계를 기다리지 않고 들어오는 쿼리를 실행할 수 있으므로 동기 통계 업데이트보다는 비동기 통계 업데이트를 사용할 때 보다 예상 가능한 쿼리 응답 시간을 얻을 수 있습니다.Your query response times might be more predictable with asynchronous statistics updates than with synchronous statistics updates because the query optimizer can execute incoming queries without waiting for up-to-date statistics. 이 방법으로 일부 쿼리의 지연을 방지할 수 있습니다.This avoids delaying some queries and not others.

  • 응용 프로그램에서 통계 업데이트를 기다리는 하나 이상의 쿼리로 인해 클라이언트 요청 제한 시간을 초과하는 경우가 있습니다.Your application has experienced client request time outs caused by one or more queries waiting for updated statistics. 동기 통계를 기다리는 경우 엄격한 시간 제한이 있는 응용 프로그램은 실패할 수 있습니다.In some cases, waiting for synchronous statistics could cause applications with aggressive time outs to fail.

    INCREMENTAL STATSINCREMENTAL STATS
    ON으로 설정된 경우 파티션 통계별로 통계가 작성됩니다.When ON, the statistics created are per partition statistics. OFF로 설정된 경우 통계 트리가 삭제되고 SQL ServerSQL Server 에서 통계를 다시 계산합니다.When OFF, the statistics tree is dropped and SQL ServerSQL Server re-computes the statistics. 기본값은 OFF입니다.The default is OFF. 이 설정은 데이터베이스수준 INCREMENTAL 속성을 재정의합니다.This setting overrides the database level INCREMENTAL property.

    큰 테이블에 새 파티션이 추가되는 경우 새 파티션을 포함하도록 통계가 업데이트되어야 합니다.When new partitions are added to a large table, statistics should be updated to include the new partitions. 하지만 전체 테이블 검색((FULLSCAN 또는 SAMPLE 옵션)에 걸리는 시간이 꽤 길 수 있습니다.However the time required to scan the entire table (FULLSCAN or SAMPLE option) might be quite long. 또한 새 파티션에 대한 통계만 필요한 경우 전체 테이블 검색이 필요하지 않습니다.Also, scanning the entire table isn't necessary because only the statistics on the new partitions might be needed. 증분 옵션은 파티션별로 통계를 작성 및 저장하며 파티션이 업데이트되는 경우 새 통계가 필요한 해당 파티션에 대해서만 통계를 새로 고칩니다.The incremental option creates and stores statistics on a per partition basis, and when updated, only refreshes statistics on those partitions that need new statistics

    파티션별 통계가 지원되지 않는 경우에는 이 옵션이 무시되고 경고가 생성됩니다.If per partition statistics are not supported the option is ignored and a warning is generated. 다음 통계 유형에 대해서는 증분 통계가 지원되지 않습니다.Incremental stats are not supported for following statistics types:

  • 기본 테이블을 기준으로 파티션 정렬되지 않은 인덱스를 사용하여 작성된 통계입니다.Statistics created with indexes that are not partition-aligned with the base table.

  • Always On 읽기 가능한 보조 데이터베이스에 대해 작성된 통계입니다.Statistics created on Always On readable secondary databases.

  • 읽기 전용 데이터베이스에 대해 작성된 통계입니다.Statistics created on read-only databases.

  • 필터링된 인덱스에 대해 작성된 통계입니다.Statistics created on filtered indexes.

  • 뷰에 대해 작성된 통계입니다.Statistics created on views.

  • 내부 테이블에 대해 작성된 통계입니다.Statistics created on internal tables.

  • 공간 인덱스 또는 XML 인덱스를 사용하여 작성된 통계입니다.Statistics created with spatial indexes or XML indexes.

||
|-|
|적용 대상: SQL Server 2014SQL Server 2014 부터 SQL Server 2017SQL Server 2017까지Applies to: SQL Server 2014SQL Server 2014 through SQL Server 2017SQL Server 2017.|

통계 작성 시기 When to Create Statistics

쿼리 최적화 프로그램은 다음과 같은 방법으로 통계를 작성합니다.The query optimizer already creates statistics in the following ways:

  1. 인덱스가 만들어진 경우 쿼리 최적화 프로그램에서 테이블 또는 뷰의 인덱스에 대한 통계를 작성합니다.The query optimizer creates statistics for indexes on tables or views when the index is created. 이러한 통계는 인덱스의 키 열에 대해 만들어집니다.These statistics are created on the key columns of the index. 인덱스가 필터링된 인덱스인 경우 쿼리 최적화 프로그램은 필터링된 인덱스로 지정된 행의 동일한 하위 집합에 대해 필터링된 통계를 작성합니다.If the index is a filtered index, the query optimizer creates filtered statistics on the same subset of rows specified for the filtered index. 필터링된 인덱스에 대한 자세한 내용은 필터링된 인덱스 만들기CREATE INDEX(Transact-SQL)를 참조하세요.For more information about filtered indexes, see Create Filtered Indexes and CREATE INDEX (Transact-SQL).

  2. AUTO_CREATE_STATISTICS가 ON이면 쿼리 최적화 프로그램은 쿼리 조건자의 단일 열에 대한 통계를 작성합니다.The query optimizer creates statistics for single columns in query predicates when AUTO_CREATE_STATISTICS is on.

    대부분의 쿼리에서 통계를 만드는 두 가지 방법을 통해 고품질의 쿼리 계획을 만들 수 있습니다. 경우에 따라서 CREATE STATISTICS 문으로 추가 통계를 작성하여 쿼리 계획을 향상시킬 수 있습니다.For most queries, these two methods for creating statistics ensure a high-quality query plan; in a few cases, you can improve query plans by creating additional statistics with the CREATE STATISTICS statement. 인덱스 또는 단일 열에 대해 통계를 작성할 때 이러한 추가 통계를 통해 쿼리 최적화 프로그램에 설명되지 않은 통계 상관 관계를 캡처할 수 있습니다.These additional statistics can capture statistical correlations that the query optimizer does not account for when it creates statistics for indexes or single columns. 응용 프로그램에 테이블 데이터의 추가 통계 상관 관계를 포함할 수 있으며 이를 통계 개체로 계산하는 경우 쿼리 최적화 프로그램에서 쿼리 계획을 향상시키도록 할 수 있습니다.Your application might have additional statistical correlations in the table data that, if calculated into a statistics object, could enable the query optimizer to improve query plans. 예를 들어 데이터 행의 하위 집합에 대한 필터링된 통계 또는 쿼리 조건자 열에 대한 여러 열 통계는 쿼리 계획을 향상시킬 수 있습니다.For example, filtered statistics on a subset of data rows or multicolumn statistics on query predicate columns might improve the query plan.

    CREATE STATISTICS 문으로 통계를 만들 때 쿼리 최적화 프로그램에서 쿼리 조건자 열에 대한 단일 열 통계를 계속해서 정기적으로 작성할 수 있도록 AUTO_CREATE_STATISTICS 옵션을 유지하는 것이 좋습니다.When creating statistics with the CREATE STATISTICS statement, we recommend keeping the AUTO_CREATE_STATISTICS option on so that the query optimizer continues to routinely create single-column statistics for query predicate columns. 쿼리 조건자에 대한 자세한 내용은 검색 조건(Transact-SQL)을 참조하세요.For more information about query predicates, see Search Condition (Transact-SQL).

    다음 중 한 가지가 적용되는 경우 CREATE STATISTICS 문으로 통계를 작성하십시오.Consider creating statistics with the CREATE STATISTICS statement when any of the following applies:

  • 데이터베이스 엔진Database Engine 튜닝 관리자가 통계 작성을 제안하는 경우The 데이터베이스 엔진Database Engine Tuning Advisor suggests creating statistics.

  • 쿼리 조건자에 동일한 인덱스에 없는 관련된 여러 열이 포함된 경우The query predicate contains multiple correlated columns that are not already in the same index.

  • 쿼리가 데이터 하위 집합에서 선택하는 경우The query selects from a subset of data.

  • 쿼리에 통계가 누락된 경우The query has missing statistics.

쿼리 조건자에 관련된 여러 열이 포함된 경우Query Predicate Contains Multiple Correlated Columns

쿼리 조건자에 열 간 관계 및 종속성을 가지는 여러 열이 포함된 경우 여러 열에 대한 통계를 통해 쿼리 계획을 향상시킬 수 있습니다.When a query predicate contains multiple columns that have cross-column relationships and dependencies, statistics on the multiple columns might improve the query plan. 여러 열 통계에는 단일 열 통계에서 사용할 수 없는 밀도라고 하는 열 간 상호 관계 통계가 포함됩니다.Statistics on multiple columns contain cross-column correlation statistics, called densities, that are not available in single-column statistics. 쿼리 결과가 여러 행 간 데이터 관계에 종속되는 경우 밀도를 사용하여 카디널리티 예상치 정확도를 높일 수 있습니다.Densities can improve cardinality estimates when query results depend on data relationships among multiple columns.

열이 이미 동일한 인덱스에 있는 경우 여러 열 통계 개체가 이미 존재하므로 여러 열 통계 개체를 직접 만들 필요가 없습니다.If the columns are already in the same index, the multicolumn statistics object already exists and it is not necessary to create it manually. 열이 동일한 인덱스에 없는 경우 CREATE STATISTICS 문을 사용하여 열에 대한 인덱스를 만들어서 여러 열 통계를 작성할 수 있습니다.If the columns are not already in the same index, you can create multicolumn statistics by creating an index on the columns or by using the CREATE STATISTICS statement. 통계 개체보다는 인덱스를 유지하는 데 더 많은 시스템 리소스가 필요합니다.It requires more system resources to maintain an index than a statistics object. 응용 프로그램에 여러 열 인덱스가 필요하지 않은 경우 인덱스를 만들지 않고 통계 개체를 만들어서 시스템 리소스를 절약할 수 있습니다.If the application does not require the multicolumn index, you can economize on system resources by creating the statistics object without creating the index.

여러 열 통계를 작성할 때 통계 개체 정의에서 열 순서는 카디널리티 예상치를 만들기 위한 밀도 효율성에 영향을 줍니다.When creating multicolumn statistics, the order of the columns in the statistics object definition affects the effectiveness of densities for making cardinality estimates. 통계 개체는 주요 열의 각 접두사에 대한 밀도를 통계 개체 정의에 저장합니다.The statistics object stores densities for each prefix of key columns in the statistics object definition. 밀도에 대한 자세한 내용은 DBCC SHOW_STATISTICS(Transact-SQL)를 참조하세요.For more information about densities, see DBCC SHOW_STATISTICS (Transact-SQL).

카디널리티 예상치에 유용한 밀도를 만들려면 쿼리 조건자의 열이 통계 개체 정의에 있는 열의 접두사 중 하나와 일치해야 합니다.To create densities that are useful for cardinality estimates, the columns in the query predicate must match one of the prefixes of columns in the statistics object definition. 다음 예에서는 LastName, MiddleName, 및 FirstName열에 대한 여러 열 통계 개체를 만듭니다.For example, the following creates a multicolumn statistics object on the columns LastName, MiddleName, and FirstName.

USE AdventureWorks2012;  
GO  
IF EXISTS (SELECT name FROM sys.stats  
    WHERE name = 'LastFirst'  
    AND object_ID = OBJECT_ID ('Person.Person'))  
DROP STATISTICS Person.Person.LastFirst;  
GO  
CREATE STATISTICS LastFirst ON Person.Person (LastName, MiddleName, FirstName);  
GO  

이 예에서 통계 개체 LastFirst 는 열 접두사 (LastName), (LastName, MiddleName) 및 (LastName, MiddleName, FirstName)에 대한 밀도를 가집니다.In this example, the statistics object LastFirst has densities for the following column prefixes: (LastName), (LastName, MiddleName), and (LastName, MiddleName, FirstName). (LastName, FirstName)에 대한 밀도는 사용할 수 없습니다.The density is not available for (LastName, FirstName). 쿼리에서 LastName 을 사용하지 않고 FirstNameMiddleName을 사용하는 경우 카디널리티 예상치에 대한 밀도는 사용할 수 없습니다.If the query uses LastName and FirstName without using MiddleName, the density is not available for cardinality estimates.

쿼리가 데이터 하위 집합에서 선택하는 경우Query Selects from a Subset of Data

쿼리 최적화 프로그램에서 단일 열 및 인덱스에 대한 통계를 만들 때 모든 행의 값에 대해 통계를 작성합니다.When the query optimizer creates statistics for single columns and indexes, it creates the statistics for the values in all rows. 쿼리가 행의 하위 집합에서 선택하고 행의 해당 하위 집합에서 데이터 분포가 고유한 경우 필터링된 통계는 쿼리 계획을 향상시킬 수 있습니다.When queries select from a subset of rows, and that subset of rows has a unique data distribution, filtered statistics can improve query plans. CREATE STATISTICS 문을 WHERE 절과 함께 사용하여 필터링된 통계를 만들어 필터 조건자 식을 정의할 수 있습니다.You can create filtered statistics by using the CREATE STATISTICS statement with the WHERE clause to define the filter predicate expression.

예를 들어 AdventureWorks2012AdventureWorks2012를 사용하면 Production.Product 테이블의 각 제품이 Production.ProductCategory 테이블의 4가지 범주인 Bikes, Components, Clothing 및 Accessories 중 하나에 속하게 됩니다.For example, using AdventureWorks2012AdventureWorks2012, each product in the Production.Product table belongs to one of four categories in the Production.ProductCategory table: Bikes, Components, Clothing, and Accessories. 각 범주의 데이터 배포는 서로 다른 가중치를 가집니다. 자전거 가중치는 13.77에서 30.0이고 구성 요소 가중치는 2.12에서 1050.00이면서 일부 NULL 값을 가지며 의류 가중치는 모두 NULL이고 액세서리 가중치 또한 NULL입니다.Each of the categories has a different data distribution for weight: bike weights range from 13.77 to 30.0, component weights range from 2.12 to 1050.00 with some NULL values, clothing weights are all NULL, and accessory weights are also NULL.

자전거를 예로 사용할 때 모든 자전거 가중치에 대한 필터링된 통계는 쿼리 최적화 프로그램에 보다 정확한 통계를 제공하므로 전체 테이블 통계 또는 Weight 열에 대한 존재하지 않는 통계에 비해 쿼리 계획의 품질을 향상시킬 수 있습니다.Using Bikes as an example, filtered statistics on all bike weights will provide more accurate statistics to the query optimizer and can improve the query plan quality compared with full-table statistics or nonexistent statistics on the Weight column. 자전거 가중치 열은 필터링된 통계의 경우에는 좋지만 가중치 조회 수가 상대적으로 적을 때 필터링된 인덱스의 경우에는 반드시 좋은 것은 아닙니다.The bike weight column is a good candidate for filtered statistics but not necessarily a good candidate for a filtered index if the number of weight lookups is relatively small. 필터링된 인덱스에서 제공하는 조회 성능의 향상은 장점이지만 필터링된 인덱스를 데이터베이스에 추가하는 것으로 인한 추가 유지 관리 및 저장 비용은 부담이 될 수 있습니다.The performance gain for lookups that a filtered index provides might not outweigh the additional maintenance and storage cost for adding a filtered index to the database.

다음 문에서는 Bikes의 모든 하위 범주에 대해 BikeWeights 로 필터링된 통계를 작성합니다.The following statement creates the BikeWeights filtered statistics on all of the subcategories for Bikes. 필터링된 조건자 식에서는 Production.ProductSubcategoryID IN (1,2,3)비교를 통해 모든 자전거 하위 범주를 열거하는 방법으로 자전거를 정의합니다.The filtered predicate expression defines bikes by enumerating all of the bike subcategories with the comparison Production.ProductSubcategoryID IN (1,2,3). Bikes 범주 이름은 Production.ProductCategory 테이블에 저장되고 필터 식의 모든 열은 동일한 테이블에 있어야 하므로 조건자에서 해당 이름을 사용할 수 없습니다.The predicate cannot use the Bikes category name because it is stored in the Production.ProductCategory table, and all columns in the filter expression must be in the same table.

USE AdventureWorks2012;
GO
IF EXISTS ( SELECT name FROM sys.stats
    WHERE name = 'BikeWeights'
    AND object_ID = OBJECT_ID ('Production.Product'))
DROP STATISTICS Production.Product.BikeWeights;
GO
CREATE STATISTICS BikeWeights
    ON Production.Product (Weight)
WHERE ProductSubcategoryID IN (1,2,3);
GO

쿼리 최적화 프로그램은 BikeWeights 로 필터링된 통계를 사용하여 25보다 가중치가 높은 모든 자전거를 선택하는 다음 쿼리의 쿼리 계획을 향상시킵니다.The query optimizer can use the BikeWeights filtered statistics to improve the query plan for the following query that selects all of the bikes that weigh more than 25.

SELECT P.Weight AS Weight, S.Name AS BikeName  
FROM Production.Product AS P  
    JOIN Production.ProductSubcategory AS S   
    ON P.ProductSubcategoryID = S.ProductSubcategoryID  
WHERE P.ProductSubcategoryID IN (1,2,3) AND P.Weight > 25  
ORDER BY P.Weight;  
GO  

쿼리에서 누락된 통계를 확인한 경우Query Identifies Missing Statistics

오류 또는 기타 이벤트로 인해 쿼리 최적화 프로그램에서 통계를 작성하지 못하는 경우 쿼리 최적화 프로그램은 통계를 사용하지 않고 쿼리 계획을 만듭니다.If an error or other event prevents the query optimizer from creating statistics, the query optimizer creates the query plan without using statistics. 쿼리 최적화 프로그램은 통계가 누락된 것으로 표시하며 다음에 쿼리가 다시 실행될 때 통계를 다시 생성하려고 합니다.The query optimizer marks the statistics as missing and attempts to regenerate the statistics the next time the query is executed.

SQL Server Management StudioSQL Server Management Studio를 사용하여 쿼리 실행 계획을 그래픽으로 표시할 때 누락된 통계는 테이블 이름을 빨간 문자열로 나타내어 경고로 표시합니다.Missing statistics are indicated as warnings (table name in red text) when the execution plan of a query is graphically displayed using SQL Server Management StudioSQL Server Management Studio. 또한 를 사용하여 Missing Column Statistics SQL Server 프로파일러SQL Server Profiler 이벤트 클래스를 모니터링하면 통계가 누락되는 시기를 나타냅니다.Additionally, monitoring the Missing Column Statistics event class by using SQL Server 프로파일러SQL Server Profiler indicates when statistics are missing. 자세한 내용은 오류 및 경고 이벤트 범주(데이터베이스 엔진)를 참조하세요.For more information, see Errors and Warnings Event Category (Database Engine).

통계가 누락된 경우 다음 단계를 수행하십시오.If statistics are missing, perform the following steps:

  • AUTO_CREATE_STATISTICS 및 AUTO_UPDATE_STATISTICS가 ON으로 설정되었는지 확인합니다.Verify that AUTO_CREATE_STATISTICS and AUTO_UPDATE_STATISTICS are on.

  • 데이터베이스가 읽기 전용이 아닌지 확인합니다.Verify that the database is not read-only. 데이터베이스가 읽기 전용인 경우 쿼리 최적화 프로그램에서 통계를 저장할 수 없습니다.If the database is read-only, the query optimizer cannot save statistics.

  • CREATE STATISTICS 문을 사용하여 누락된 통계를 작성합니다.Create the missing statistics by using the CREATE STATISTICS statement.

    읽기 전용 데이터베이스 또는 읽기 전용 스냅숏에 대한 통계가 없거나 유효하지 않을 경우 데이터베이스 엔진Database Enginetempdb에서 임시 통계를 만들어 유지 관리합니다.When statistics on a read-only database or read-only snapshot are missing or stale, the 데이터베이스 엔진Database Engine creates and maintains temporary statistics in tempdb. 데이터베이스 엔진Database Engine 에서 임시 통계를 만드는 경우 통계 이름에는 접미사 _readonly_database_statistic이 추가되므로 영구적 통계와 임시 통계를 구별할 수 있습니다.When the 데이터베이스 엔진Database Engine creates temporary statistics, the statistics name is appended with the suffix _readonly_database_statistic to differentiate the temporary statistics from the permanent statistics. 접미사 _readonly_database_statistic은 SQL ServerSQL Server에서 생성하는 통계용으로 예약되어 있습니다.The suffix _readonly_database_statistic is reserved for statistics generated by SQL ServerSQL Server. 읽기/쓰기 데이터베이스에서 임시 통계에 대한 스크립트를 만들어 재현할 수 있습니다.Scripts for the temporary statistics can be created and reproduced on a read-write database. 스크립팅된 경우 Management StudioManagement Studio 에서는 통계 이름의 접미사를 _readonly_database_statistic에서 _readonly_database_statistic_scripted로 변경합니다.When scripted, Management StudioManagement Studio changes the suffix of the statistics name from _readonly_database_statistic to _readonly_database_statistic_scripted.

    SQL ServerSQL Server 에서만 임시 통계를 만들고 업데이트할 수 있습니다.Only SQL ServerSQL Server can create and update temporary statistics. 그러나 임시 통계를 삭제하고 통계 속성을 모니터링하는 데는 영구적 통계에 사용하는 것과 동일한 도구를 사용할 수 있습니다.However, you can delete temporary statistics and monitor statistics properties using the same tools that you use for permanent statistics:

  • DROP STATISTICS (Transact-SQL) 문으로 작성된 통계에 적용됩니다.Delete temporary statistics using the DROP STATISTICS (Transact-SQL) statement.

  • sys.statssys.stats_columns 카탈로그 뷰를 사용하여 통계를 모니터링합니다.Monitor statistics using the sys.stats and sys.stats_columns catalog views. sys_stats 에는 영구적 통계와 임시 통계를 나타내는 is_temporary 열이 포함되어 있습니다.sys_stats includes the is_temporary column, to indicate which statistics are permanent and which are temporary.

    임시 통계는 tempdb에 저장되므로 SQL ServerSQL Server 서비스를 다시 시작하면 모든 임시 통계가 사라집니다.Because temporary statistics are stored in tempdb, a restart of the SQL ServerSQL Server service causes all temporary statistics to disappear.

통계 업데이트 시기 When to Update Statistics

쿼리 최적화 프로그램은 통계가 최신이 아닌 통계가 되는 시점을 확인한 다음 쿼리 계획에 필요할 때 통계를 업데이트합니다.The query optimizer determines when statistics might be out-of-date and then updates them when they are needed for a query plan. 경우에 따라 AUTO_UPDATE_STATISTICS를 ON으로 설정할 때보다 더 자주 통계를 업데이트하여 쿼리 계획을 향상시키고 쿼리 성능을 높일 수 있습니다.In some cases you can improve the query plan and therefore improve query performance by updating statistics more frequently than occur when AUTO_UPDATE_STATISTICS is on. UPDATE STATISTICS 문 또는 저장 프로시저 sp_updatestats를 사용하여 통계를 업데이트할 수 있습니다.You can update statistics with the UPDATE STATISTICS statement or the stored procedure sp_updatestats.

통계를 업데이트하면 쿼리가 최신 통계로 컴파일되지만Updating statistics ensures that queries compile with up-to-date statistics. 쿼리도 다시 컴파일됩니다.However, updating statistics causes queries to recompile. 쿼리 계획 향상과 쿼리 재컴파일 소요 시간 간의 성능 균형을 유지해야 하므로 통계를 너무 자주 업데이트하지 않는 것이 좋습니다.We recommend not updating statistics too frequently because there is a performance tradeoff between improving query plans and the time it takes to recompile queries. 구체적인 성능 균형 유지의 정도는 응용 프로그램에 따라 달라집니다.The specific tradeoffs depend on your application.

UPDATE STATISTICS 또는 sp_updatestats를 사용하여 통계를 업데이트할 때 AUTO_UPDATE_STATISTICS를 ON으로 유지하여 쿼리 최적화 프로그램에서 계속해서 정기적으로 통계를 업데이트하는 것이 좋습니다.When updating statistics with UPDATE STATISTICS or sp_updatestats, we recommend keeping AUTO_UPDATE_STATISTICS set to ON so that the query optimizer continues to routinely update statistics. 열, 인덱스, 테이블 또는 인덱싱된 뷰에 대한 통계를 업데이트하는 방법은 UPDATE STATISTICS(Transact-SQL)를 참조하세요.For more information about how to update statistics on a column, an index, a table, or an indexed view, see UPDATE STATISTICS (Transact-SQL). 데이터베이스의 모든 사용자 정의 테이블 및 내부 테이블에 대한 통계를 업데이트하는 방법은 저장 프로시저 sp_updatestats(Transact-SQL)를 참조하세요.For information about how to update statistics for all user-defined and internal tables in the database, see the stored procedure sp_updatestats (Transact-SQL).

통계가 마지막으로 업데이트된 시점을 확인하려면 STATS_DATE 함수를 사용합니다.To determine when statistics were last updated, use the STATS_DATE function.

다음과 같은 경우 통계를 업데이트할 것을 고려하십시오.Consider updating statistics for the following conditions:

  • 쿼리 실행 시간이 느린 경우Query execution times are slow.

  • 삽입 작업이 오름차순 또는 내림차순 키 열에 대해 발생하는 경우Insert operations occur on ascending or descending key columns.

  • 유지 관리 작업 이후After maintenance operations.

쿼리 실행 시간이 느린 경우Query Execution Times Are Slow

쿼리 응답 시간이 느리거나 예측할 수 없는 경우 추가 문제 해결 단계를 수행하기 전에 쿼리에 최신 통계가 포함되었는지 확인하십시오.If query response times are slow or unpredictable, ensure that queries have up-to-date statistics before performing additional troubleshooting steps.

삽입 작업이 오름차순 또는 내림차순 키 열에 대해 발생하는 경우Insert Operations Occur on Ascending or Descending Key Columns

IDENTITY 또는 실시간 타임스탬프 열과 같은 오름차순 또는 내림차순 키 열에 대한 통계의 경우 쿼리 최적화 프로그램이 수행하는 것보다 더 자주 통계를 업데이트해야 할 수도 있습니다.Statistics on ascending or descending key columns, such as IDENTITY or real-time timestamp columns, might require more frequent statistics updates than the query optimizer performs. 삽입 작업에서는 새 값을 오름차순 또는 내림차순 열에 추가합니다.Insert operations append new values to ascending or descending columns. 추가된 행 수가 통계 업데이트를 트리거하기에는 너무 작을 수 있습니다.The number of rows added might be too small to trigger a statistics update. 통계가 최신 통계가 아니고 쿼리가 가장 최근에 추가된 행에서 선택하는 경우 현재 통계는 이러한 새 값에 대한 카디널리티 예상치를 포함하지 않습니다.If statistics are not up-to-date and queries select from the most recently added rows, the current statistics will not have cardinality estimates for these new values. 이로 인해 카디널리티 예상치가 부정확해지고 쿼리 성능이 저하될 수 있습니다.This can result in inaccurate cardinality estimates and slow query performance.

예를 들어 가장 최근의 판매 주문 날짜에 대한 카디널리티 예상치를 포함하도록 통계가 업데이트되지 않은 경우 가장 최근의 판매 주문 날짜에서 선택하는 쿼리는 부정확한 카디널리티 예상치를 포함할 수 있습니다.For example, a query that selects from the most recent sales order dates will have inaccurate cardinality estimates if the statistics are not updated to include cardinality estimates for the most recent sales order dates.

유지 관리 작업 이후After Maintenance Operations

테이블 삭제와 같이 데이터 분포를 변경하는 유지 관리 작업을 수행한 후 또는 많은 양의 행에 대한 대량 삽입을 수행한 후 통계를 업데이트하십시오.Consider updating statistics after performing maintenance procedures that change the distribution of data, such as truncating a table or performing a bulk insert of a large percentage of the rows. 이렇게 하면 이후에 쿼리에서 자동 통계 업데이트를 기다리는 동안 쿼리 처리에 지연이 생기는 것을 방지할 수 있습니다.This can avoid future delays in query processing while queries wait for automatic statistics updates.

인덱스 다시 작성, 다시 구성, 조각 모음 등의 작업은 데이터 분포를 변경하지 않습니다.Operations such as rebuilding, defragmenting, or reorganizing an index do not change the distribution of data. 따라서 ALTER INDEX REBUILD, DBCC REINDEX, DBCC INDEXDEFRAG 또는 ALTER INDEX REORGANIZE 작업을 수행한 후에는 통계를 업데이트할 필요가 없습니다.Therefore, you do not need to update statistics after performing ALTER INDEX REBUILD, DBCC REINDEX, DBCC INDEXDEFRAG, or ALTER INDEX REORGANIZE operations. ALTER INDEX REBUILD 또는 DBCC DBREINDEX를 사용하여 테이블 또는 뷰에 대한 인덱스를 다시 작성하는 경우 쿼리 최적화 프로그램에서 통계를 업데이트하지만 이 통계 업데이트는 인덱스를 다시 만드는 과정에서 생성됩니다.The query optimizer updates statistics when you rebuild an index on a table or view with ALTER INDEX REBUILD or DBCC DBREINDEX, however; this statistics update is a byproduct of re-creating the index. DBCC INDEXDEFRAG 또는 ALTER INDEX REORGANIZE 작업 이후에는 쿼리 최적화 프로그램에서 통계를 업데이트하지 않습니다.The query optimizer does not update statistics after DBCC INDEXDEFRAG or ALTER INDEX REORGANIZE operations.

통계를 효율적으로 사용하는 쿼리 Queries That Use Statistics Effectively

쿼리 조건자에서 지역 변수, 복잡한 식 등의 일부 쿼리 구현은 만족스럽지 못한 쿼리 계획을 만들 수 있습니다.Certain query implementations, such as local variables and complex expressions in the query predicate, can lead to suboptimal query plans. 이를 방지하려면 효율적인 통계 사용을 위한 쿼리 설계 지침을 따르는 것이 좋습니다.Following query design guidelines for using statistics effectively can help to avoid this. 쿼리 조건자에 대한 자세한 내용은 검색 조건(Transact-SQL)을 참조하세요.For more information about query predicates, see Search Condition (Transact-SQL).

쿼리 조건자에 사용된 식, 변수 및 함수에 대한 카디널리티 예상치 정확도를 높이기 위해 효율적으로 통계를 사용하는 쿼리 설계 지침을 적용하여 쿼리 계획을 향상시킬 수 있습니다.You can improve query plans by applying query design guidelines that use statistics effectively to improve cardinality estimates for expressions, variables, and functions used in query predicates. 쿼리 최적화 프로그램에서 식, 변수 또는 함수 값을 알지 못하는 경우 히스토그램에서 조회할 값을 알 수 없으므로 히스토그램에서 최상의 카디널리티 예상치를 검색할 수 없습니다.When the query optimizer does not know the value of an expression, variable, or function, it does not know which value to lookup in the histogram and therefore cannot retrieve the best cardinality estimate from the histogram. 대신 쿼리 최적화 프로그램은 히스토그램에서 샘플링된 모든 행에 대한 고유한 값마다 평균 행 수에 대한 카디널리티 예상치를 예측합니다.Instead, the query optimizer bases the cardinality estimate on the average number of rows per distinct value for all of the sampled rows in the histogram. 이로 인해 카디널리티 예상치가 만족스럽지 못하고 쿼리 성능이 저하될 수 있습니다.This leads to suboptimal cardinality estimates and can hurt query performance.

다음 지침에서는 카디널리티 예상치 정확도를 높여 쿼리 계획을 향상시킬 수 있도록 쿼리를 작성하는 방법에 대해 설명합니다.The following guidelines describe how to write queries to improve query plans by improving cardinality estimates.

식에 대한 카디널리티 예상치 정확도 향상Improving Cardinality Estimates for Expressions

식에 대한 카디널리티 예상치 정확도를 높이려면 다음 지침에 따르십시오.To improve cardinality estimates for expressions, follow these guidelines:

  • 가능하면 상수가 포함된 단순한 식을 사용하십시오.Whenever possible, simplify expressions with constants in them. 쿼리 최적화 프로그램에서는 카디널리티 예상치를 확인하기 전에 상수가 포함된 모든 함수와 식을 평가하지 않습니다.The query optimizer does not evaluate all functions and expressions containing constants prior to determining cardinality estimates. 예를 들어 ABS(-100) to 100) 식을 단순화하십시오.For example, simplify the expression ABS(-100) to 100.

  • 식에서 여러 변수를 사용하는 경우 식에 대해 계산된 열을 만든 다음 계산된 열에 대해 통계 또는 인덱스를 만드십시오.If the expression uses multiple variables, consider creating a computed column for the expression and then create statistics or an index on the computed column. 예를 들어 WHERE PRICE + Tax > 100 식에 대해 계산 열을 만드는 경우 쿼리 조건자 Price + Tax은 보다 정확한 카디널리티 예상치를 가질 수 있습니다.For example, the query predicate WHERE PRICE + Tax > 100 might have a better cardinality estimate if you create a computed column for the expression Price + Tax.

변수 및 함수에 대한 카디널리티 예상치 정확도 향상Improving Cardinality Estimates for Variables and Functions

변수 및 함수에 대한 카디널리티 예상치 정확도를 높이려면 다음 지침에 따르십시오.To improve the cardinality estimates for variables and functions, follow these guidelines:

  • 쿼리 조건자에서 지역 변수를 사용하는 경우 지역 변수 대신 매개 변수를 사용하여 쿼리를 다시 작성하십시오.If the query predicate uses a local variable, consider rewriting the query to use a parameter instead of a local variable. 쿼리 최적화 프로그램에서 쿼리 실행 계획을 만들 때 지역 변수 값은 알 수 없습니다.The value of a local variable is not known when the query optimizer creates the query execution plan. 쿼리에서 매개 변수를 사용할 때 쿼리 최적화 프로그램은 저장 프로시저에 전달되는 첫 번째 실제 매개 변수 값에 대한 카디널리티 예상치를 사용합니다.When a query uses a parameter, the query optimizer uses the cardinality estimate for the first actual parameter value that is passed to the stored procedure.

  • 다중 문 테이블 반환 함수의 결과를 저장하려면 표준 테이블 또는 임시 테이블을 사용하십시오.Consider using a standard table or temporary table to hold the results of multi-statement table-valued functions. 쿼리 최적화 프로그램은 다중 문 테이블 반환 함수에 대한 통계를 작성하지 않습니다.The query optimizer does not create statistics for multi-statement table-valued functions. 이 방법을 사용하는 경우 쿼리 최적화 프로그램은 테이블 열에 대한 통계를 작성하고 이러한 통계를 사용하여 보다 향상된 쿼리 계획을 만들 수 있습니다.With this approach the query optimizer can create statistics on the table columns and use them to create a better query plan.

  • 테이블 변수 대신 표준 테이블 또는 임시 테이블을 사용하십시오.Consider using a standard table or temporary table as a replacement for table variables. 쿼리 최적화 프로그램은 테이블 변수에 대한 통계를 작성하지 않습니다.The query optimizer does not create statistics for table variables. 이 방법을 사용하는 경우 쿼리 최적화 프로그램은 테이블 열에 대한 통계를 작성하고 이러한 통계를 사용하여 보다 향상된 쿼리 계획을 만들 수 있습니다.With this approach the query optimizer can create statistics on the table columns and use them to create a better query plan. 임시 테이블 사용과 테이블 변수 사용에는 각각 장단점이 있습니다. 저장 프로시저에 테이블 변수를 사용하면 임시 테이블에 비해 저장 프로시저를 다시 컴파일하는 횟수가 줄어듭니다.There are tradeoffs in determining whether to use a temporary table or a table variable; Table variables used in stored procedures cause fewer recompilations of the stored procedure than temporary tables. 응용 프로그램에 따라 테이블 변수 대신 임시 테이블을 사용하면 성능이 향상되지 않을 수도 있습니다.Depending on the application, using a temporary table instead of a table variable might not improve performance.

  • 이미 전달된 매개 변수를 사용하는 쿼리가 저장 프로시저에 포함되어 있는 경우 쿼리에서 매개 변수 값을 사용하기 전에 저장 프로시저 내의 매개 변수 값을 변경하지 마십시오.If a stored procedure contains a query that uses a passed-in parameter, avoid changing the parameter value within the stored procedure before using it in the query. 쿼리에 대한 카디널리티 예상치는 업데이트된 값이 아닌 이미 전달된 매개 변수 값을 기준으로 합니다.The cardinality estimates for the query are based on the passed-in parameter value and not the updated value. 매개 변수 값이 변경되지 않도록 두 개의 저장 프로시저를 사용하여 쿼리를 다시 작성할 수 있습니다.To avoid changing the parameter value, you can rewrite the query to use two stored procedures.

    예를 들어 Sales.GetRecentSales 인 경우 다음 @date 저장 프로시저에서는 @date is NULL매개 변수의 값을 변경합니다.For example, the following stored procedure Sales.GetRecentSales changes the value of the parameter @date when @date is NULL.

    USE AdventureWorks2012;  
    GO  
    IF OBJECT_ID ( 'Sales.GetRecentSales', 'P') IS NOT NULL  
        DROP PROCEDURE Sales.GetRecentSales;  
    GO  
    CREATE PROCEDURE Sales.GetRecentSales (@date datetime)  
    AS BEGIN  
        IF @date is NULL  
            SET @date = DATEADD(MONTH, -3, (SELECT MAX(ORDERDATE) FROM Sales.SalesOrderHeader))  
        SELECT * FROM Sales.SalesOrderHeader h, Sales.SalesOrderDetail d  
        WHERE h.SalesOrderID = d.SalesOrderID  
        AND h.OrderDate > @date  
    END  
    GO  
    

    저장 프로시저 Sales.GetRecentSales 에 대한 첫 번째 호출에서 NULL을 @date 매개 변수에 전달하면 쿼리 조건자가 @date = NULL 과 함께 호출되지 않은 경우에도 쿼리 최적화 프로그램에서 @date = NULL에 대한 카디널리티 예상치와 함께 저장 프로시저를 컴파일합니다.If the first call to the stored procedure Sales.GetRecentSales passes a NULL for the @date parameter, the query optimizer will compile the stored procedure with the cardinality estimate for @date = NULL even though the query predicate is not called with @date = NULL. 실제 쿼리 결과에서 이 카디널리티 예상치는 행 수와 많이 다를 수 있습니다.This cardinality estimate might be significantly different than the number of rows in the actual query result. 그 결과 쿼리 최적화 프로그램에서 만족스럽지 못한 쿼리 계획을 선택할 수 있습니다.As a result, the query optimizer might choose a suboptimal query plan. 이를 방지하기 위해 다음과 같이 저장 프로시저를 두 개의 프로시저로 다시 작성할 수 있습니다.To help avoid this, you can rewrite the stored procedure into two procedures as follows:

    USE AdventureWorks2012;  
    GO  
    IF OBJECT_ID ( 'Sales.GetNullRecentSales', 'P') IS NOT NULL  
        DROP PROCEDURE Sales.GetNullRecentSales;  
    GO  
    CREATE PROCEDURE Sales.GetNullRecentSales (@date datetime)  
    AS BEGIN  
        IF @date is NULL  
            SET @date = DATEADD(MONTH, -3, (SELECT MAX(ORDERDATE) FROM Sales.SalesOrderHeader))  
        EXEC Sales.GetNonNullRecentSales @date;  
    END  
    GO  
    IF OBJECT_ID ( 'Sales.GetNonNullRecentSales', 'P') IS NOT NULL  
        DROP PROCEDURE Sales.GetNonNullRecentSales;  
    GO  
    CREATE PROCEDURE Sales.GetNonNullRecentSales (@date datetime)  
    AS BEGIN  
        SELECT * FROM Sales.SalesOrderHeader h, Sales.SalesOrderDetail d  
        WHERE h.SalesOrderID = d.SalesOrderID  
        AND h.OrderDate > @date  
    END  
    GO  
    

쿼리 힌트를 사용하여 카디널리티 예상치 정확도 향상Improving Cardinality Estimates with Query Hints

지역 변수에 대한 카디널리티 예상치 정확도를 높이기 위해 RECOMPILE과 함께 OPTIMIZE FOR 또는 OPTIMIZE FOR UNKNOWN 쿼리 힌트를 사용할 수 있습니다.To improve cardinality estimates for local variables, you can use the OPTIMIZE FOR or OPTIMIZE FOR UNKNOWN query hints with RECOMPILE. 자세한 내용은 쿼리 힌트(Transact-SQL)를 참조하세요.For more information, see Query Hints (Transact-SQL).

일부 응용 프로그램의 경우 쿼리를 실행할 때마다 다시 컴파일하는 데 너무 많은 시간이 걸릴 수 있습니다.For some applications, recompiling the query each time it executes might take too much time. RECOMPILE 옵션을 사용하지 않는 경우에도 OPTIMIZE FOR 쿼리 힌트가 도움이 될 수 있습니다.The OPTIMIZER FOR query hint can help even if you don't use the RECOMPILE option. 예를 들어 특정 날짜를 지정하기 위해 OPTIMIZER FOR 옵션을 저장 프로시저 Sales.GetRecentSales에 추가할 수 있습니다.For example, you could add an OPTIMIZER FOR option to the stored procedure Sales.GetRecentSales to specify a specific date. 다음 예에서는 OPTIMIZER FOR 옵션을 Sales.GetRecentSales 프로시저에 추가합니다.The following example adds the OPTIMIZE FOR option to the Sales.GetRecentSales procedure.

USE AdventureWorks2012;  
GO  
IF OBJECT_ID ( 'Sales.GetRecentSales', 'P') IS NOT NULL  
    DROP PROCEDURE Sales.GetRecentSales;  
GO  
CREATE PROCEDURE Sales.GetRecentSales (@date datetime)  
AS BEGIN  
    IF @date is NULL  
        SET @date = DATEADD(MONTH, -3, (SELECT MAX(ORDERDATE) FROM Sales.SalesOrderHeader))  
    SELECT * FROM Sales.SalesOrderHeader h, Sales.SalesOrderDetail d  
    WHERE h.SalesOrderID = d.SalesOrderID  
    AND h.OrderDate > @date  
    OPTION ( OPTIMIZE FOR ( @date = '2004-05-01 00:00:00.000'))  
END;  
GO  

계획 지침을 사용하여 카디널리티 예상치 정확도 향상Improving Cardinality Estimates with Plan Guides

일부 응용 프로그램의 경우 쿼리를 변경할 수 없거나 RECOMPILE 쿼리 힌트 사용으로 인해 너무 많은 컴파일이 필요해서 통계 설계 지침이 적용되지 않을 수 있습니다.For some applications, query design guidelines might not apply because you cannot change the query or using the RECOMPILE query hint might be cause too many recompiles. 응용 프로그램 공급업체와 함께 응용 프로그램 변경 내용을 조사하는 동안 쿼리 동작을 제어할 수 있도록 계획 지침을 사용하여 USE PLAN과 같은 기타 힌트를 지정할 수 있습니다.You can use plan guides to specify other hints, such as USE PLAN, to control the behavior of the query while investigating application changes with the application vendor. 계획 지침에 대한 자세한 내용은 Plan Guides를 참조하십시오.For more information about plan guides, see Plan Guides.

관련 항목:See Also

CREATE STATISTICS(Transact-SQL) CREATE STATISTICS (Transact-SQL)
UPDATE STATISTICS(Transact-SQL) UPDATE STATISTICS (Transact-SQL)
sp_updatestats(Transact-SQL) sp_updatestats (Transact-SQL)
DBCC SHOW_STATISTICS(Transact-SQL) DBCC SHOW_STATISTICS (Transact-SQL)
ALTER DATABASE SET 옵션(Transact-SQL) ALTER DATABASE SET Options (Transact-SQL)
DROP STATISTICS(Transact-SQL) DROP STATISTICS (Transact-SQL)
CREATE INDEX(Transact-SQL) CREATE INDEX (Transact-SQL)
ALTER INDEX(Transact-SQL) ALTER INDEX (Transact-SQL)
필터링된 인덱스 만들기 Create Filtered Indexes