Усеченная таблица и статистика ОБНОВЛЕНИЯ - PullRequest
4 голосов
/ 13 ноября 2009

Нужно ли обновлять статистику таблицы после вызова таблицы усечения или она обновляется автоматически?

В: Нужно ли вызывать «UPDATE STATISTICS» после усечения таблицы?

Ответы [ 3 ]

7 голосов
/ 13 ноября 2009

Статистика не обновляется автоматически, пока статистика не понадобится снова. иначе, TRUNCATE не делает этого. Так что "нет".

Первоначальный ответ был «Да», потому что он не является автоматическим как часть TRUNCATE. Зависит от того, как вы читаете вопрос: -)

Помните, что статистика обновляется автоматически при необходимости запроса (например, номер изменения строки). Из " Статистика индекса " в BOL

Обновление статистики инициируется всякий раз, когда статистика, используемая в плане выполнения запроса, не проходит проверку для текущей статистики

Один способ проверки с использованием STATS_DATE ...

SELECT
   name AS index_name, 
   STATS_DATE(object_id, index_id)
FROM
   sys.indexes 
WHERE
   object_id = OBJECT_ID('MyTruncatedTable')


Редактировать : Я хотел убедиться, что: -)

Вы увидите, что статистика обновляется только инструкциями SELECT, а не INSERT, DELETE или TRUNCATE

IF OBJECT_ID('dbo.foo') IS NOT NULL DROP TABLE dbo.foo
CREATE TABLE dbo.foo (
    bar int NOT NULL IDENTITY (1, 1) PRIMARY KEY,
    thing int NOT NULL
)
CREATE INDEX IX_thing ON dbo.foo (thing)

INSERT dbo.foo (thing) SELECT c1.object_id FROM sys.columns c1, sys.columns c2
SELECT
   name AS index_name, 
   STATS_DATE(object_id, index_id) AS AfterLoad
FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.foo')

SELECT DISTINCT thing FROM dbo.foo ORDER BY thing DESC
SELECT
   name AS index_name, 
   STATS_DATE(object_id, index_id) AS AfterFirstQuery
FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.foo')

DELETE TOP (50000) dbo.foo
SELECT
   name AS index_name, 
   STATS_DATE(object_id, index_id) AS AfterDelete
FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.foo')

SELECT DISTINCT thing FROM dbo.foo ORDER BY thing DESC
SELECT
   name AS index_name, 
   STATS_DATE(object_id, index_id) AS After2ndQuery
FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.foo')

TRUNCATE TABLE dbo.foo
SELECT
   name AS index_name, 
   STATS_DATE(object_id, index_id) AS AfterTruncate
FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.foo')

SELECT DISTINCT thing FROM dbo.foo ORDER BY thing DESC
SELECT
   name AS index_name, 
   STATS_DATE(object_id, index_id) AS After3rdQuery
FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.foo')
7 голосов
/ 13 ноября 2009

Это зависит от того, как ваш администратор настроил статистику. Обычный подход будет еженедельным обслуживанием. Тогда вы можете либо дождаться запуска задания, либо обновить статистику вручную.

Также есть возможность автоматически обновлять статистику :

При автоматическом обновлении статистики опция AUTO_UPDATE_STATISTICS включена, оптимизатор запросов определяет, когда статистика может быть устаревшей и затем обновляет их, когда они используются по запросу.

Это, вероятно, будет пересчитано после усечения.

Вы можете включить автообновления как:

ALTER DATABASE AdventureWorks
    SET AUTO_UPDATE_STATISTICS ON;

И обновить статистику вручную:

UPDATE STATISTICS Sales.SalesOrderDetail

Чтобы проверить текущий возраст вашей статистики, запустите:

SELECT 
    object_name = Object_Name(ind.object_id),
    IndexName = ind.name,
    StatisticsDate = STATS_DATE(ind.object_id, ind.index_id)
FROM SYS.INDEXES ind
order by STATS_DATE(ind.object_id, ind.index_id) desc
2 голосов
/ 13 ноября 2009

Поскольку у вас есть нет данных , это будет бессмысленно, пока данные не будут вставлены, а затем вы захотите обновить статистику.

Не забывайте, что вы можете автоматически обновлять статистику, а также запускать и обновлять статистические задания ежедневно / еженедельно и т. Д. *

Если это все еще вызывает серьезную озабоченность, просто усечите, а затем обновите статистику в таблице.

...