Vous pouvez garder à l’esprit les points suivants lorsque vous vous souciez de la mise à jour des statistiques (copiées à partir de Reconstruire des index et mettre à jour des statistiques (Benjamin Nevarez)
Par défaut, l' UPDATE STATISTICS
instruction utilise uniquement un échantillon d'enregistrements de la table. Utiliser UPDATE STATISTICS WITH FULLSCAN
va scanner toute la table.
Par défaut, l' UPDATE STATISTICS
instruction met à jour les statistiques d'index et de colonne. Utiliser cette COLUMNS
option ne mettra à jour que les statistiques de colonne. Utiliser cette INDEX
option ne mettra à jour que les statistiques d'index.
La reconstruction d'un index , par exemple en utilisant, ALTER INDEX … REBUILD
mettra également à jour les statistiques d'index avec l'équivalent de l'utilisation WITH FULLSCAN
sauf si la table est partitionnée, auquel cas les statistiques sont uniquement échantillonnées (s'applique à SQL Server 2012 et versions ultérieures).
Les statistiques créées manuellement à l'aide de CREATE STATISTICS
ne sont mises à jour par aucune ALTER INDEX ... REBUILD
opération, y compris ALTER TABLE ... REBUILD
. ALTER TABLE ... REBUILD
met à jour les statistiques pour l'index clusterisé, s'il en existe un défini sur la table en cours de reconstruction.
Réorganiser un index , par exemple, utiliser ALTER INDEX … REORGANIZE
ne met à jour aucune statistique.
La réponse courte est que vous devez utiliser UPDATE STATISTICS
pour mettre à jour les statistiques de colonne et qu'une reconstruction d'index mettra à jour uniquement les statistiques d'index. Vous pouvez forcer la mise à jour de toutes les statistiques d'une table, y compris index-stats et statistiques créées manuellement, avec la UPDATE STATISTICS (tablename) WITH FULLSCAN;
syntaxe.
Le code suivant illustre les règles encapsulées ci-dessus:
Tout d'abord, nous allons créer une table avec quelques colonnes et un index clusterisé:
USE tempdb;
IF OBJECT_ID(N'dbo.SomeTable', N'U') IS NOT NULL
DROP TABLE dbo.SomeTable;
CREATE TABLE dbo.SomeTable
(
rn int NOT NULL IDENTITY(1,1)
CONSTRAINT pk
PRIMARY KEY NONCLUSTERED
, i int NOT NULL INDEX i
, d sysname NOT NULL
) ON [PRIMARY] WITH (DATA_COMPRESSION = NONE);
CREATE UNIQUE CLUSTERED INDEX cx ON dbo.SomeTable (i, d);
CREATE STATISTICS d ON dbo.SomeTable (d) WITH FULLSCAN;
INSERT INTO dbo.SomeTable (d, i)
SELECT c1.name, c1.id
FROM sys.syscolumns c1;
Cette requête indique la date de la dernière mise à jour de chaque objet de statistiques:
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
Les résultats montrent qu'aucune mise à jour n'a encore eu lieu, ce qui est correct puisque nous venons de créer la table:
╔═══════════════╦═══════════╦═══════════╗
║ ObjectName ║ StatsName ║ StatsDate
╠═══════════════╬═══════════╬═══════════╣
║ dbo.SomeTable cx NULL
║ dbo.SomeTable i NULL
║ dbo.SomeTable pk ║ NULL
║ dbo.SomeTable d ║ NULL
╚═══════════════╩═══════════╩═══════════╝
Reconstruisons la table entière et voyons si cela met à jour les statistiques:
ALTER TABLE dbo.SomeTable REBUILD;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ║ StatsName ║ StatsDate
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable cx 2018-09-17 14: 09: 13.590
║ dbo.SomeTable i NULL
║ dbo.SomeTable pk ║ NULL
║ dbo.SomeTable d ║ NULL
╚═══════════════╩═══════════╩═════════════════════ ════╝
Les résultats montrent que seules les statistiques de l' index clusterisé ont été mises à jour.
Ensuite, nous effectuons une UPDATE STATS
opération discrète :
UPDATE STATISTICS dbo.SomeTable(d) WITH FULLSCAN;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
Comme vous pouvez le constater, nous venons de mettre à jour les statistiques de la d
colonne:
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ║ StatsName ║ StatsDate
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable cx 2018-09-17 14: 09: 13.590
║ dbo.SomeTable i NULL
║ dbo.SomeTable pk ║ NULL
Dbo.SomeTable d ║ 2018-09-17 14: 09: 13.597
╚═══════════════╩═══════════╩═════════════════════ ════╝
Maintenant, nous allons mettre à jour les statistiques sur toute la table:
UPDATE STATISTICS dbo.SomeTable WITH FULLSCAN;
SELECT ObjectName = sc.name + N'.' + o.name
, StatsName = s.name
, StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ║ StatsName ║ StatsDate
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable cx 2018-09-17 14: 09: 13.600
Dbo.SomeTable i ║ 2018-09-17 14: 09: 13.600
║ dbo.SomeTable pk 2018-09-17 14: 09: 13.603
Dbo.SomeTable d ║ 2018-09-17 14: 09: 13.607
╚═══════════════╩═══════════╩═════════════════════ ════╝
Comme vous pouvez le constater, le seul moyen de vérifier que toutes les statistiques ont été mises à jour est de les mettre à jour manuellement ou de mettre à jour le tableau entier UPDATE STATISTICS (table);
.
REINDEX
mise à jour des statistiques de colonne est un effet secondaire de la reconstruction de l'index - vous n'avez pas besoin de mettre à jour les statistiques. Les données dans la table ne changent pas. Ce sont les mêmes données, il a seulement déplacé son emplacement sur le plateau en rotation (lorsqu'une page est réorganisée), ou b) assis sur une page différente (dans le cas d'une reconstruction). Donc: une réindexation fait des statistiques de mise à jour (certains): il n'y a pas besoin de le faire.