Benjamin Nevarez est un consultant indépendant basé à Los Angeles, en Californie, spécialisé dans le réglage et l'optimisation des requêtes SQL Server. Il est l'auteur de "SQL Server 2014 Query Tuning &Optimization" et "Inside the SQL Server Query Optimizer" et co-auteur de "SQL Server 2012 Internals". Avec plus de 20 ans d'expérience dans les bases de données relationnelles, Benjamin a également été conférencier lors de nombreuses conférences SQL Server, notamment le PASS Summit, SQL Server Connections et SQLBits. Le blog de Benjamin peut être trouvé à http://www.benjaminnevarez.com et il peut également être contacté par e-mail à admin à benjaminnevarez dot com et sur twitter à @BenjaminNevarez.
Un problème majeur avec la mise à jour des statistiques dans les grandes tables dans SQL Server est que la table entière doit toujours être analysée, par exemple lors de l'utilisation du WITH FULLSCAN
option, même si seules les données récentes ont changé. Cela est également vrai lors de l'utilisation du partitionnement :même si seule la partition la plus récente a changé depuis la dernière mise à jour des statistiques, la mise à jour des statistiques nécessite à nouveau d'analyser la table entière, y compris toutes les partitions qui n'ont pas changé. Les statistiques incrémentielles, une nouvelle fonctionnalité de SQL Server 2014, peuvent aider à résoudre ce problème.
À l'aide de statistiques incrémentielles, vous pouvez mettre à jour uniquement la ou les partitions dont vous avez besoin et les informations sur ces partitions seront fusionnées avec les informations existantes pour créer l'objet statistique final. Un autre avantage des statistiques incrémentielles est que le pourcentage de modifications de données nécessaires pour déclencher une mise à jour automatique des statistiques fonctionne désormais au niveau de la partition, ce qui signifie essentiellement que désormais seulement 20 % des lignes modifiées (modifications sur la colonne de statistiques principale) par partition sont nécessaires. Malheureusement, l'histogramme est toujours limité à 200 étapes pour l'ensemble de l'objet de statistiques dans cette version de SQL Server.
Examinons un exemple de la façon dont vous pouvez mettre à jour les statistiques au niveau d'une partition pour explorer son comportement au moins à partir de SQL Server 2014 CTP2. Nous devons d'abord créer une table partitionnée à l'aide de la base de données AdventureWorks2012 :
CREATE PARTITION FUNCTION TransactionRangePF1 (DATETIME) AS RANGE RIGHT FOR VALUES ( '20071001', '20071101', '20071201', '20080101', '20080201', '20080301', '20080401', '20080501', '20080601', '20080701', '20080801' ); GO CREATE PARTITION SCHEME TransactionsPS1 AS PARTITION TransactionRangePF1 TO ( [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY] ); GO CREATE TABLE dbo.TransactionHistory ( TransactionID INT NOT NULL, -- not bothering with IDENTITY here ProductID INT NOT NULL, ReferenceOrderID INT NOT NULL, ReferenceOrderLineID INT NOT NULL DEFAULT (0), TransactionDate DATETIME NOT NULL DEFAULT (GETDATE()), TransactionType NCHAR(1) NOT NULL, Quantity INT NOT NULL, ActualCost MONEY NOT NULL, ModifiedDate DATETIME NOT NULL DEFAULT (GETDATE()), CONSTRAINT CK_TransactionType CHECK (UPPER(TransactionType) IN (N'W', N'S', N'P')) ) ON TransactionsPS1 (TransactionDate); GO
Remarque :Pour plus de détails sur le partitionnement et la CREATE PARTITION FUNCTION / SCHEME
instructions, veuillez vous référer aux Tables et index partitionnés dans la documentation en ligne.
Nous avons actuellement des données pour remplir 12 partitions. Commençons par remplir d'abord seulement 11.
INSERT INTO dbo.TransactionHistory SELECT * FROM Production.TransactionHistory WHERE TransactionDate < '2008-08-01';
Si nécessaire, vous pouvez utiliser l'instruction suivante pour inspecter le contenu des partitions :
SELECT * FROM sys.partitions WHERE object_id = OBJECT_ID('dbo.TransactionHistory');
Créons un objet de statistiques incrémentales en utilisant le CREATE STATISTICS
déclaration avec le nouveau INCREMENTAL
clause définie sur ON
(OFF
est la valeur par défaut) :
CREATE STATISTICS incrstats ON dbo.TransactionHistory(TransactionDate) WITH FULLSCAN, INCREMENTAL = ON;
Vous pouvez également créer des statistiques incrémentielles lors de la création d'un index à l'aide du nouveau STATISTICS_INCREMENTAL
clause du CREATE INDEX
déclaration.
Vous pouvez inspecter l'objet de statistiques créé à l'aide de DBCC
:
DBCC SHOW_STATISTICS('dbo.TransactionHistory', incrstats);
Entre autres choses, vous remarquerez que l'histogramme comporte 200 étapes (seulement les 3 dernières présentées ici) :
RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | |
198 | 2008-07-25 00:00:00.000 | 187 | 100 | 2 |
199 | 2008-07-27 00:00:00.000 | 103 | 101 | 1 |
200 | 2008-07-31 00:00:00.000 | 281 | 131 | 3 |
Résultats DBCC initiaux
Nous avons donc déjà le maximum d'étapes dans un objet de statistiques. Que se passerait-il si vous ajoutiez des données à une nouvelle partition ? Ajoutons des données à la partition 12 :
INSERT INTO dbo.TransactionHistory SELECT * FROM Production.TransactionHistory WHERE TransactionDate >= '2008-08-01';
Maintenant, nous mettons à jour l'objet de statistiques en utilisant l'instruction suivante :
UPDATE STATISTICS dbo.TransactionHistory(incrstats) WITH RESAMPLE ON PARTITIONS(12);
Notez la nouvelle syntaxe spécifiant la partition, où vous pouvez spécifier plusieurs partitions, séparées par une virgule. Les UPDATE STATISTICS
L'instruction lit les partitions spécifiées, puis fusionne leurs résultats avec l'objet statistique existant pour créer les statistiques globales. Notez le RESAMPLE
clause; cela est nécessaire car les statistiques de partition doivent avoir les mêmes taux d'échantillonnage à fusionner pour créer les statistiques globales. Bien que seule la partition spécifiée ait été analysée, vous pouvez voir que SQL Server a réorganisé l'histogramme. Les trois dernières étapes affichent maintenant les données de la partition ajoutée. Vous pouvez également comparer l'original avec le nouvel histogramme pour d'autres différences mineures :
RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | |
197 | 2008-07-31 00:00:00.000 | 150 | 131 | 2 |
198 | 2008-08-12 00:00:00.000 | 300 | 36 | 9 |
199 | 2008-08-22 00:00:00.000 | 229 | 43 | 7 |
200 | 2008-09-03 00:00:00.000 | 363 | 37 | 11 |
Résultats DBCC après la mise à jour incrémentielle
Si, pour une raison quelconque, vous souhaitez désactiver les statistiques incrémentielles, vous pouvez utiliser l'instruction suivante pour revenir au comportement d'origine (ou éventuellement supprimer simplement l'objet de statistiques et en créer un nouveau).
UPDATE STATISTICS dbo.TransactionHistory(incrstats) WITH FULLSCAN, INCREMENTAL = OFF;
Après avoir désactivé les statistiques incrémentielles, essayer de mettre à jour une partition comme indiqué précédemment renverra le message d'erreur suivant :
Msg 9111, Niveau 16, État 1La syntaxe MISE À JOUR DES STATISTIQUES SUR LES PARTITIONS n'est pas prise en charge pour les statistiques non incrémentielles.
Enfin, vous pouvez également activer des statistiques incrémentielles pour vos statistiques automatiques au niveau de la base de données, si nécessaire. Cela nécessite le INCREMENTAL = ON
clause dans la ALTER DATABASE
déclaration et nécessite évidemment aussi AUTO_CREATE_STATISTICS
réglé sur ON
.