СтатистикаStatistics

ОБЛАСТЬ ПРИМЕНЕНИЯ: даSQL Server даБаза данных SQL AzureдаХранилище данных SQL AzureдаParallel Data WarehouseAPPLIES TO: yesSQL Server yesAzure SQL Database yesAzure SQL Data Warehouse yesParallel Data Warehouse

Оптимизатор запросов использует статистику для создания планов запросов, которые повышают производительность запросов.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 some 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

Статистика для оптимизации запросов — это большие двоичные объекты (BLOB-объекты), содержащие статистические сведения о распределении значений в одном или нескольких столбцах таблицы или индексированного представления.Statistics for query optimization are binary large objects (BLOBs) 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 seek вместо оператора index scan, который потребляет больше ресурсов, если благодаря этому повысится производительность запроса.For example, depending on your predicates, the Query Optimizer could use cardinality estimates to choose the index seek operator instead of the more resource-intensive index scan operator, if doing so improves 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.

ГистограммаHistogram

Гистограмма измеряет частоту появления каждого различающегося значения в наборе данных.A histogram measures the frequency of occurrence for each distinct value in a data set. Оптимизатор запросов вычисляет гистограмму для значений столбца в первом ключевом столбце объекта статистики, выбирая значения столбцов путем статистической выборки строк или при помощи полного просмотра всех строк в таблице или представлении.The query optimizer computes a histogram on the column values in the first key column of the statistics object, selecting the column values by statistically sampling the rows or by performing a full scan of all rows in the table or view. Если гистограмма создается на основе выбранного набора строк, то сохраняемые итоговые значения количества строк и количества различающихся значений являются приблизительными и не всегда выражаются целыми числами.If the histogram is created from a sampled set of rows, the stored totals for number of rows and number of distinct values are estimates and do not need to be whole integers.

Примечание

Гистограммы в SQL ServerSQL Server создаются только для одного столбца, которым является первый столбец в наборе ключевых столбцов объекта статистики.Histograms in SQL ServerSQL Server are only built for a single column-the first column in the set of key columns of the statistics object.

Чтобы создать гистограмму, оптимизатор запросов сортирует значения столбцов, вычисляет количество значений, совпадающих с каждым различающимся значением столбца, а затем осуществляет статистическую обработку значений столбцов с получением непрерывных шагов гистограммы, максимальное количество которых составляет 200.To create the histogram, the query optimizer sorts the column values, computes the number of values that match each distinct column value and then aggregates the column values into a maximum of 200 contiguous histogram steps. Каждый шаг гистограммы включает диапазон значений столбцов, за которым следует значение столбца, представляющее собой верхнюю границу.Each histogram step includes a range of column values followed by an upper bound column value. В этот диапазон входят все возможные значения столбца между граничными значениями, за исключением самих граничных значений.The range includes all possible column values between boundary values, excluding the boundary values themselves. Наименьшим из отсортированных значений столбца является верхнее граничное значение первого шага гистограммы.The lowest of the sorted column values is the upper boundary value for the first histogram step.

Если говорить подробнее, SQL ServerSQL Server создает гистограмму на основе упорядоченного набора значений столбцов за три шага:In more detail, SQL ServerSQL Server creates the histogram from the sorted set of column values in three steps:

  • Инициализация гистограммы: на первом шаге обрабатывается последовательность значений, начиная с начала сортированного набора; собирается до 200 значений range_high_key, equal_rows, range_rows и distinct_range_rows (range_rows и distinct_range_rows всегда равны нулю на этом шаге).Histogram initialization: In the first step, a sequence of values starting at the beginning of the sorted set is processed, and up to 200 values of range_high_key, equal_rows, range_rows, and distinct_range_rows are collected (range_rows and distinct_range_rows are always zero during this step). Первый шаг заканчивается, когда все входные значения обработаны или найдено 200 значений.The first step ends either when all input has been exhausted, or when 200 values have been found.
  • Сканирование со слиянием корзин: каждое дополнительное значение из первого столбца ключа статистики обрабатывается на втором шаге в порядке сортировки; каждое последующее значение либо добавляется в последний диапазон, либо в конце создается новый диапазон (это возможно потому, что входные значения сортированы).Scan with bucket merge: Each additional value from the leading column of the statistics key is processed in the second step, in sorted order; each successive value is either added to the last range or a new range at the end is created (this is possible because the input values are sorted). Если создается новый диапазон, одна пара существующих, расположенных по соседству диапазонов сворачивается в один.If a new range is created, then one pair of existing, neighboring ranges is collapsed into a single range. Эта пара диапазонов выбирается с целью уменьшения информационных потерь.This pair of ranges is selected in order to minimize information loss. Этот способ использует алгоритм максимальной разности для сведения к минимуму числа шагов в гистограмме и вместе с тем максимального увеличения разницы между граничными значениями.This method uses a maximum difference algorithm to minimize the number of steps in the histogram while maximizing the difference between the boundary values. Число шагов после сворачивания диапазонов на протяжении этого шага остается равным 200.The number of steps after collapsing ranges stays at 200 throughout this step.
  • Консолидация гистограммы: на третьем шаге могут быть свернуты дополнительные диапазоны, если это не приведет к значительной потере данных.Histogram consolidation: In the third step, more ranges may be collapsed if a significant amount of information is not lost. Число шагов гистограммы может быть меньше, чем количество различающихся значений, даже для столбцов, в которых число граничных точек меньше 200.The number of histogram steps can be fewer than the number of distinct values, even for columns with fewer than 200 boundary points. Таким образом, даже если в столбце содержится более 200 уникальных значений, гистограмма может содержать менее 200 шагов.Therefore, even if the column has more than 200 unique values, the histogram may have less than 200 steps. Для столбца, состоящего только из уникальных значений, консолидированная гистограмма будет содержать как минимум три шага.For a column consisting of only unique values, then the consolidated histogram will have a minimum of three steps.

Примечание

Если гистограмма была построена на основе выборки, а не полного сканирования, значения equal_rows, range_rows, distinct_range_rows и average_range_rows будут рассчитаны и не обязательно будут являться целыми числами.If the histogram has been built using a sample rather than fullscan, then the values of equal_rows, range_rows, and distinct_range_rows and average_range_rows are estimated, and therefore they do not need to be whole integers.

На следующей диаграмме показана гистограмма с шестью шагами.The following diagram shows a histogram with six steps. Первый шаг — это область слева от первого верхнего граничного значения.The area to the left of the first upper boundary value is the first step.

Для каждого шага гистограммы (см. выше):For each histogram step above:

  • Полужирной линией обозначено верхнее граничное значение (range_high_key) и количество его вхождений (equal_rows).Bold line represents the upper boundary value (range_high_key) and the number of times it occurs (equal_rows)

  • Закрашенная область слева от range_high_key обозначает диапазон значений столбца и среднее количество вхождений каждого значения столбца (average_range_rows).Solid area left of range_high_key represents the range of column values and the average number of times each column value occurs (average_range_rows). В первом шаге гистограммы значение average_range_rows всегда равно 0.The average_range_rows for the first histogram step is always 0.

  • Пунктирные линии обозначают выбранные значения, которые используются для оценки общего числа различающихся значений (distinct_range_rows) и общего числа значений в диапазоне (range_rows).Dotted lines represent the sampled values used to estimate total number of distinct values in the range (distinct_range_rows) and total number of values in the range (range_rows). Оптимизатор запросов использует range_rows и distinct_range_rows для вычисления average_range_rows и не хранит выбранные значения.The query optimizer uses range_rows and distinct_range_rows to compute average_range_rows and does not store the sampled values.

Вектор плотностейDensity Vector

Плотность определяет число дубликатов в заданных столбце или комбинации столбцов и рассчитывается как 1/(число уникальных значений).Density is information about the number of duplicates in a given column or combination of columns and it is calculated as 1/(number of distinct values). Оптимизатор запросов использует плотности для улучшения оценок количества элементов для запросов, которые возвращают данные нескольких столбцов из одной таблицы или индексированного представления.The query optimizer uses densities to enhance cardinality estimates for queries that return multiple columns from the same table or indexed view. По мере повышения плотности избирательность значения повышается.As density decreases, selectivity of a value increases. Например, в таблице, представляющей автомобили, много автомобилей имеют одного производителя, но каждый автомобиль имеет уникальный идентификационный номер транспортного средства (VIN).For example, in a table representing cars, many cars have the same manufacturer, but each car has a unique vehicle identification number (VIN). Индекс по VIN является более избирательным, чем индекс по производителям, так как VIN с меньшей плотностью, чем производитель.An index on the VIN is more selective than an index on the manufacturer, because VIN has lower density than manufacturer.

Примечание

Частота определяет число вхождений каждого уникального значения в первый ключевой столбец объекта статистики и рассчитывается как (число строк) * плотность.Frequency is information about the occurrence of each distinct value in the first key column of the statistics object, and is calculated as row count * density. В столбцах с уникальными значениями максимальная частота равна 1.A maximum frequency of 1 can be found in columns with unique values.

Вектор плотностей содержит по одной плотности для каждого префикса столбцов объекта статистики.The density vector contains one density for each prefix of columns in the statistics object. Например, если объект статистики имеет ключевые столбцы CustomerId, ItemId и Price, плотность вычисляется для каждого из следующих префиксов столбцов.For example, if a statistics object has the key columns CustomerId, ItemId and Price, density is calculated on each of the following column prefixes.

Префикс столбцаColumn prefix Префикс, по которому вычисляется плотностьDensity calculated on
(CustomerId)(CustomerId) Строки с совпадающими значениями CustomerIdRows with matching values for CustomerId
(CustomerId, ItemId)(CustomerId, ItemId) Строки с совпадающими значениями CustomerId и ItemId.Rows with matching values for CustomerId and ItemId
(CustomerId, ItemId, Price)(CustomerId, ItemId, Price) Строки с совпадающими значениями CustomerId, ItemId и Price.Rows with matching values for CustomerId, ItemId, and Price

Отфильтрованная статистика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.

Параметры статистики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_STATISTICSAUTO_CREATE_STATISTICS Option

Если включен параметр AUTO_CREATE_STATISTICS (автоматическое создание статистики), оптимизатор запросов при необходимости создает статистику по отдельным столбцам в предикате запроса, чтобы улучшить оценку кратности для плана запроса.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 
INNER 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_STATISTICSAUTO_UPDATE_STATISTICS Option

Если включен параметр AUTO_UPDATE_STATISTICS (автоматическое обновление статистики), оптимизатор запросов определяет, устарела ли статистика, и при необходимости обновляет ее, если она используется в запросе.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 (12.x)SQL Server 2014 (12.x), SQL ServerSQL Server применяет пороговое значение в зависимости от процента измененных строк.Up to SQL Server 2014 (12.x)SQL Server 2014 (12.x), SQL ServerSQL Server uses a threshold based on the percent of rows changed. Это значение не зависит от числа строк в таблице.This is regardless of the number of rows in the table. Пороговое значение:The threshold is:

    • Если на момент оценки статистических данных кратность в таблице не превышала 500, обновление выполняется для каждых 500 модификаций.If the table cardinality was 500 or less at the time statistics were evaluated, update for every 500 modifications.
    • Если на момент оценки статистических данных кратность в таблице превышала 500, обновление выполняется для каждых 500 + 20 % модификаций.If the table cardinality was above 500 at the time statistics were evaluated, update for every 500 + 20 percent of modifications.
  • Начиная с версии SQL Server 2016 (13.x)SQL Server 2016 (13.x) и при уровне совместимости базы данных 130 SQL ServerSQL Server используется пороговое значение для динамического обновления статистических данных по убыванию. Значение изменяется в зависимости от числа строк в таблице.Starting with SQL Server 2016 (13.x)SQL Server 2016 (13.x) and under the database compatibility level 130, SQL ServerSQL Server uses a decreasing, dynamic statistics update threshold that adjusts according to the number of rows in the table. Оно вычисляется как квадратный корень из произведения текущего значения кратности в таблице и 1000.This is calculated as the square root of the product of 1000 and the current table cardinality. Например, если таблица содержит 2 миллиона строк, значение вычисляется как квадратный корень из (1000 * 2000000) = 44721,359.For example if your table contains 2 million rows, then the calculation is? sqrt (1000 * 2000000) = 44721.359. Благодаря этому изменению статистика для больших таблиц будет обновляться чаще.With this change, statistics on large tables will be updated more often. Но если уровень совместимости для базы данных ниже 130, применяется пороговое значение SQL Server 2014 (12.x)SQL Server 2014 (12.x).However, if a database has a compatibility level below 130, then the SQL Server 2014 (12.x)SQL Server 2014 (12.x) threshold applies. ??

Важно!

Начиная с версии SQL Server 2008 R2SQL Server 2008 R2 и до SQL Server 2014 (12.x)SQL Server 2014 (12.x) или с SQL Server 2016 (13.x)SQL Server 2016 (13.x) и до SQL Server 2017SQL Server 2017 при уровне совместимости базы данных ниже 130 применяется флаг трассировки 2371 и SQL ServerSQL Server используется пороговое значение для динамического обновления статистических данных по убыванию. Значение изменяется в зависимости от числа строк в таблице.Starting with SQL Server 2008 R2SQL Server 2008 R2 through SQL Server 2014 (12.x)SQL Server 2014 (12.x), or in SQL Server 2016 (13.x)SQL Server 2016 (13.x) through SQL Server 2017SQL Server 2017 under database compatibility level lower than 130, use trace flag 2371 and SQL ServerSQL Server will use a decreasing, dynamic statistics update threshold that adjusts according to the number of rows in the table.

Оптимизатор запросов проверяет наличие устаревшей статистики перед компиляцией запроса и до выполнения кэшированного плана запроса.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 EngineDatabase Engine проверяет, ссылается ли план запроса на актуальную статистику.Before executing a cached query plan, the Компонент Database EngineDatabase 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.

Дополнительные сведения см. в разделе об управлении поведением Autostat (AUTO_UPDATE_STATISTICS) в SQL Server.For more information about controlling AUTO_UPDATE_STATISTICS, see Controlling Autostat (AUTO_UPDATE_STATISTICS) behavior in SQL Server.

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. По умолчанию параметр асинхронного обновления статистики отключен, и оптимизатор запросов обновляет статистику синхронно.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.

Примечание

Чтобы задать параметр асинхронного обновления статистических данных в SQL Server Management StudioSQL Server Management Studio, нужно установить значение True для параметров Автоматическое обновление статистики и Асинхронное автоматическое обновление статистики в разделе Параметры окна Свойства базы данных.To set the asynchronous statistics update option in SQL Server Management StudioSQL Server Management Studio, in the Options page of the Database Properties window, both Auto Update Statistics and Auto Update Statistics Asynchronously options need to be set to True.

Обновление статистики может выполняться синхронно (режим по умолчанию) или асинхронно.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.

INCREMENTALINCREMENTAL

Если параметр INCREMENTAL инструкции CREATE STATISTICS имеет значение ON, статистика создается по секциям.When INCREMENTAL option of CREATE STATISTICS is 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. Дополнительные сведения о создании добавочной статистики см. в разделе CREATE STATISTICS (Transact-SQL).For more information about creating incremental statistics, see CREATE STATISTICS (Transact-SQL). Дополнительные сведения об автоматическом создании статистики по секциям см. в разделах Свойства базы данных (страница параметров) и Параметры ALTER DATABASE SET (Transact-SQL).For more information about creating per partition statistics automatically, see Database Properties (Options Page) and ALTER DATABASE SET Options (Transact-SQL).

Когда в большую таблицу добавляются новые секции, статистики должны быть обновлены для включения новых секций.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.
  • Статистики, созданные в доступных для чтения базах данных-получателях AlwaysOn.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 2014 (12.x)SQL Server 2014 (12.x) до SQL Server 2017SQL Server 2017.Applies to: SQL Server 2014 (12.x)SQL Server 2014 (12.x) 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, оптимизатор запросов создает статистику для отдельных столбцов в предикатах запросов.The Query Optimizer creates statistics for single columns in query predicates when AUTO_CREATE_STATISTICS is on.

Мы слушаем! Если вы обнаружили в этой статье устаревшие или недостоверные сведения, например инструкции или пример кода, сообщите нам.We are listening: If you find something outdated or incorrect in this article, such as a step or a code example, please tell us. Можно воспользоваться кнопкой Эта страница в разделе Отзывы внизу страницы.You can click the This page button in the Feedback section at the bottom of this page. Обычно мы читаем отзывы про материалы по SQL на следующий день.We read every item of feedback about SQL, typically the next day. Благодарим вас.Thanks.

Для большинства запросов эти два метода создания статистики обеспечивают создание высококачественного плана запроса. В некоторых случаях план запроса можно усовершенствовать, создав дополнительную статистику с помощью инструкции 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 EngineDatabase Engine ) рекомендует создание статистики.The Компонент Database EngineDatabase 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. Дополнительные сведения о плотности см. в разделе Вектор плотности на этой странице.For more information about densities, see Density section in this page.

Чтобы получить значения плотности, полезные для оценки количества элементов, столбцы в предикате запроса должны совпадать с одним из префиксов столбцов в определении объекта статистики.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 и FirstName , но не используется MiddleName, то плотность будет недоступна для оценки количества элементов.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: велосипеды, запасные части, одежда и аксессуары.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.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.

В примере с категорией Bikes отфильтрованная статистика по весу всех велосипедов предоставит оптимизатору запросов более точную статистику, а также повысит качество плана запроса по сравнению с полнотабличной статистикой или отсутствующей статистикой по столбцу 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.

Следующая инструкция создает отфильтрованную статистику BikeWeights по всем подкатегориям из категории Bikes.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 ProfilerSQL Server Profiler.Additionally, monitoring the Missing Column Statistics event class by using Приложение SQL Server ProfilerSQL Server Profiler indicates when statistics are missing. Дополнительные сведения см. в статье Категория событий "Ошибки и предупреждения" (компонент Database Engine).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.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, a new statistics object cannot be saved.
  • Создайте отсутствующую статистику с помощью инструкции CREATE STATISTICS.Create the missing statistics by using the CREATE STATISTICS statement.

Если статистика для доступной только для чтения базы данных или доступного только для чтения моментального снимка отсутствует или устарела, компонент Компонент Database EngineDatabase Engine создаст и будет поддерживать временную статистику в базе данных tempdb.When statistics on a read-only database or read-only snapshot are missing or stale, the Компонент Database EngineDatabase Engine creates and maintains temporary statistics in tempdb. Когда компонент Компонент Database EngineDatabase Engine создает временную статистику, перед именем статистики добавляется суффикс _readonly_database_statistic, чтобы временную статистику можно было отличить от постоянной.When the Компонент Database EngineDatabase 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.Delete temporary statistics using the DROP STATISTICS statement.
  • Мониторинг статистики ведется с помощью представлений каталога sys.stats и sys.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.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 включенным, чтобы оптимизатор запросов продолжал регулярно обновлять статистику.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).

Чтобы определить время последнего обновления статистики, используйте функцию sys.dm_db_stats_properties или STATS_DATE.To determine when statistics were last updated, use the sys.dm_db_stats_properties or STATS_DATE functions.

Обновление статистики рекомендуется в следующих ситуациях.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 DBREINDEX, DBCC INDEXDEFRAG и ALTER INDEX REORGANIZE не нужно обновлять статистику.Therefore, you do not need to update statistics after performing ALTER INDEX REBUILD, DBCC DBREINDEX, 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.

Совет

Начиная с версии SQL Server 2016 (13.x)SQL Server 2016 (13.x) с пакетом обновления 1 и накопительным пакетом обновления 4 используйте параметр PERSIST_SAMPLE_PERCENT для CREATE STATISTICS (Transact-SQL) или UPDATE STATISTICS (Transact-SQL), чтобы задать и сохранить определенный процент выборки для последующих обновлений статистических данных, в которых такой процент явно не указан.Starting with SQL Server 2016 (13.x)SQL Server 2016 (13.x) SP1 CU4, use the PERSIST_SAMPLE_PERCENT option of CREATE STATISTICS (Transact-SQL) or UPDATE STATISTICS (Transact-SQL), to set and retain a specific sampling percentage for subsequent statistic updates that do not explicitly specify a sampling percentage.

Автоматическое управление индексами и статистикойAutomatic index and statistics management

Используйте такие решения, как Адаптивная дефрагментация индексов, чтобы автоматически управлять дефрагментацией индексов и обновлениями статистики для одной базы данных или нескольких.Leverage solutions such as Adaptive Index Defrag to automatically manage index defragmentation and statistics updates for one or more databases. Эта процедура автоматически выбирает, следует ли перестроить или реорганизовать индекс, сверяясь с уровнем фрагментации и другими параметрами, и обновляет статистику на основе линейных пороговых значений.This procedure automatically chooses whether to rebuild or reorganize an index according to its fragmentation level, amongst other parameters, and update statistics with a linear threshold.

Запросы, при которых эффективно используется статистика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. Дополнительные сведения о гистограммах см. в разделе Гистограмма на этой странице или в статье sys.dm_db_stats_histogram (Transact-SQL).For more information about histograms, see histogram section in this page or sys.dm_db_stats_histogram.

Следующие рекомендации показывают, как составлять запросы, чтобы усовершенствовать планы запроса благодаря улучшению оценки количества элементов.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) до 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.

  • Для хранения результатов функции с табличным значением с несколькими инструкциями рекомендуем использовать стандартную или временную таблицу (mstvf).Consider using a standard table or temporary table to hold the results of multi-statement table-valued functions (mstvf). Оптимизатор запросов не создает статистику для функций с табличным значением с несколькими инструкциями.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 имеет значение 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 для параметра @date передается значение NULL, оптимизатор запросов выполнит компиляцию хранимой процедуры с оценкой кратности для @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

Чтобы улучшить оценку кратности для локальных переменных, можно использовать указания запросов OPTIMIZE FOR <value> или OPTIMIZE FOR UNKNOWN с параметром RECOMPILE.To improve cardinality estimates for local variables, you can use the OPTIMIZE FOR <value> 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. Указание запроса OPTIMIZE FOR может повысить производительность даже в случае, когда параметр RECOMPILE не используется.The OPTIMIZE FOR query hint can help even if you don't use the RECOMPILE option. Например, можно добавить параметр OPTIMIZE FOR к хранимой процедуре Sales.GetRecentSales, чтобы указать определенную дату.For example, you could add an OPTIMIZE FOR option to the stored procedure Sales.GetRecentSales to specify a specific date. В следующем примере параметр OPTIMIZE 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. Дополнительные сведения о структурах планов см. в разделе Руководства планов.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
Controlling Autostat (AUTO_UPDATE_STATISTICS) behavior in SQL Server (Управление поведением Autostat (AUTO_UPDATE_STATISTICS) в SQL Server)Controlling Autostat (AUTO_UPDATE_STATISTICS) behavior in SQL Server
STATS_DATE (Transact-SQL) STATS_DATE (Transact-SQL)
sys.dm_db_stats_properties (Transact-SQL) sys.dm_db_stats_properties (Transact-SQL)
sys.dm_db_stats_histogram (Transact-SQL)sys.dm_db_stats_histogram (Transact-SQL)
sys.statssys.stats
sys.stats_columns (Transact-SQL) sys.stats_columns (Transact-SQL)
Адаптивная дефрагментация индексовAdaptive Index Defrag