Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Statistiques incrémentielles SQL Server 2014

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 1
La 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 .