sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server 2014 Incremental Statistics

Benjamin Nevarez er en uafhængig konsulent baseret i Los Angeles, Californien, som har specialiseret sig i tuning og optimering af SQL Server-forespørgsler. Han er forfatter til "SQL Server 2014 Query Tuning &Optimization" og "Inside the SQL Server Query Optimizer" og medforfatter til "SQL Server 2012 Internals". Med mere end 20 års erfaring i relationelle databaser har Benjamin også været foredragsholder ved mange SQL Server-konferencer, herunder PASS Summit, SQL Server Connections og SQLBits. Benjamins blog kan findes på http://www.benjaminnevarez.com, og han kan også nås via e-mail på admin på benjaminnevarez dot com og på twitter på @BenjaminNevarez.

Et stort problem ved opdatering af statistik i store tabeller i SQL Server er, at hele tabellen altid skal scannes, for eksempel ved brug af WITH FULLSCAN mulighed, selvom kun de seneste data er ændret. Dette gælder også, når du bruger partitionering:selvom kun den nyeste partition var ændret siden sidste gang, statistik blev opdateret, krævede opdatering af statistik igen for at scanne hele tabellen inklusive alle de partitioner, der ikke ændrede sig. Inkrementelle statistikker, en ny SQL Server 2014-funktion, kan hjælpe med dette problem.

Ved at bruge trinvis statistik kan du kun opdatere den eller de partitioner, du har brug for, og oplysningerne om disse partitioner vil blive flettet sammen med den eksisterende information for at skabe det endelige statistikobjekt. En anden fordel ved inkrementel statistik er, at den procentdel af dataændringer, der kræves for at udløse en automatisk opdatering af statistik, nu fungerer på partitionsniveauet, hvilket grundlæggende betyder, at der nu kun kræves 20% af de ændrede rækker (ændringer på den førende statistikkolonne) pr. partition. Desværre er histogrammet stadig begrænset til 200 trin for hele statistikobjektet i denne version af SQL Server.

Lad os se på et eksempel på, hvordan du kan opdatere statistik på et partitionsniveau for at udforske dens adfærd i det mindste fra og med SQL Server 2014 CTP2. Først skal vi oprette en partitioneret tabel ved hjælp af AdventureWorks2012-databasen:

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

Bemærk:For detaljer om partitionering og CREATE PARTITION FUNCTION / SCHEME udsagn henvises til Opdelte tabeller og indekser i Books Online.

Vi har i øjeblikket data til at udfylde 12 partitioner. Lad os starte med først at udfylde 11.

INSERT INTO dbo.TransactionHistory
SELECT * FROM Production.TransactionHistory
WHERE TransactionDate < '2008-08-01';

Hvis det er nødvendigt, kan du bruge følgende erklæring til at inspicere indholdet af partitionerne:

SELECT * FROM sys.partitions
  WHERE object_id = OBJECT_ID('dbo.TransactionHistory');

Lad os oprette et inkrementelt statistikobjekt ved hjælp af CREATE STATISTICS sætning med den nye INCREMENTAL klausul sat til ON (OFF er standard):

CREATE STATISTICS incrstats ON dbo.TransactionHistory(TransactionDate) 
  WITH FULLSCAN, INCREMENTAL = ON;

Du kan også oprette trinvis statistik, mens du opretter et indeks ved hjælp af den nye STATISTICS_INCREMENTAL klausul i CREATE INDEX erklæring.

Du kan inspicere det oprettede statistikobjekt ved hjælp af DBCC :

DBCC SHOW_STATISTICS('dbo.TransactionHistory', incrstats);

Du vil blandt andet bemærke, at histogrammet har 200 trin (kun de sidste 3 vist her):

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

Oprindelige DBCC-resultater

Så vi har allerede det maksimale antal trin i et statistikobjekt. Hvad ville der ske, hvis du tilføjer data til en ny partition? Lad os tilføje data til partition 12:

INSERT INTO dbo.TransactionHistory 
SELECT * FROM Production.TransactionHistory 
WHERE TransactionDate >= '2008-08-01';

Nu opdaterer vi statistikobjektet ved hjælp af følgende sætning:

UPDATE STATISTICS dbo.TransactionHistory(incrstats) 
  WITH RESAMPLE ON PARTITIONS(12);

Bemærk den nye syntaks, der angiver partitionen, hvor du kan angive flere partitioner, adskilt med komma. UPDATE STATISTICS sætning læser de angivne partitioner og fusionerer derefter deres resultater med det eksisterende statistikobjekt for at bygge den globale statistik. Bemærk RESAMPLE klausul; dette er påkrævet, da partitionsstatistikker skal have de samme samplingsfrekvenser for at blive flettet for at bygge den globale statistik. Selvom kun den angivne partition blev scannet, kan du se, at SQL Server har omarrangeret histogrammet. De sidste tre trin viser nu data for den tilføjede partition. Du kan også sammenligne originalen med det nye histogram for andre mindre forskelle:

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

DBCC-resultater efter den trinvise opdatering

Hvis du af en eller anden grund vil deaktivere den trinvise statistik, kan du bruge følgende erklæring til at gå tilbage til den oprindelige adfærd (eller eventuelt bare slippe statistikobjektet og oprette et nyt).

UPDATE STATISTICS dbo.TransactionHistory(incrstats) 
  WITH FULLSCAN, INCREMENTAL = OFF;

Efter deaktivering af den trinvise statistik vil forsøg på at opdatere en partition som vist tidligere returnere følgende fejlmeddelelse:

Msg 9111, Level 16, State 1
OPDATERING STATISTIK PÅ PARTITIONER syntaks er ikke understøttet for ikke-inkrementel statistik.

Endelig kan du også aktivere inkrementel statistik for din automatiske statistik på databaseniveau, hvis det er nødvendigt. Dette kræver INCREMENTAL = ON klausul i ALTER DATABASE sætning og kræver naturligvis også AUTO_CREATE_STATISTICS indstillet til ON .


  1. Avanceret databaseovervågning og -styring til TimescaleDB

  2. Variabler, der skelner mellem store og små bogstaver, i SQL Server

  3. Trunc datofelt i mysql som Oracle

  4. Nested Loop Join in Oracle 11g