Dove sono archiviate fisicamente le statistiche in SQL Server?


27

Dove sono archiviate fisicamente le statistiche utilizzate da Query Optimizer in un file di database di SQL Server e nel pool di buffer?

Più specificamente, c'è un modo per capire le pagine usate dalle statistiche usando DMV e / o DBCC?

Possiedo entrambi i manuali SQL Server 2008 Internals e SQL Server Internals e risoluzione dei problemi e nessuno di loro parla della struttura fisica delle statistiche; se lo fanno non sono in grado di trovare queste informazioni.


1
Quando si crea una copia solo statistica del database, viene visualizzato un file binario STATS_STREAMche non ho mai verificato se si trova qualcosa nel file stesso.
Martin Smith,

2
Le statistiche vengono create da una funzione aggregata solo interna ( StatMan) che genera un BLOB (ironicamente, quel nome viene evidenziato come una funzione in una finestra di query SSMS). Logicamente, le statistiche sono associate a un indice o a una serie di colonne di una tabella, quindi vorrei iniziare esaminando le tabelle di metadati interne alla ricerca di una binaryo varbinarycolonna che porterà al BLOB. Questo dovrebbe essere visualizzabile usando DBCC PAGE, ma probabilmente non altrimenti perché è tutto interno.
Jon Seigel,

1
@ivanmp Ho modificato la tua domanda per maggiore chiarezza poiché molti dei DBA più inesperti non sapranno cos'è una BP o un QO.
Max Vernon,

2
Una volta ero presente, sysindexes.statblobma dal 2005 è tornato NULLe la posizione è completamente priva di documenti, recuperabile solo (di cui sono a conoscenza) DBCC SHOW_STATISTICS(o, i) WITH STATS_STREAM;.
Aaron Bertrand

1
Ho trovato le statistiche dell'indice - sono presenti sys.sysidxstats- sembra che ci sia un puntatore LOB in quella tabella. Non sono sicuro di dove siano ancora le statistiche delle colonne; potrebbero essere in quella tabella e c'è una typecolonna.
Jon Seigel,

Risposte:


30

Trovati.

  1. Crea una tabella con un semplice oggetto stats.

    CREATE DATABASE splunge;
    GO
    USE splunge;
    GO
    CREATE TABLE dbo.foo(bar INT, munge INT);
    GO
    CREATE STATISTICS x ON dbo.foo(bar);
    CREATE STATISTICS y ON dbo.foo(munge);
    GO
    INSERT dbo.foo SELECT s1.[object_id], s2.[object_id]
      FROM sys.objects AS s1
      CROSS JOIN sys.objects AS s2;
    GO
    UPDATE STATISTICS dbo.foo;
    GO
  2. Connettersi utilizzando il DAC ( ADMIN:Server[\instance]).

  3. Esegui le seguenti query:

    DBCC SHOW_STATISTICS('dbo.foo', 'x') WITH STATS_STREAM;
    DBCC SHOW_STATISTICS('dbo.foo', 'y') WITH STATS_STREAM;
    
    SELECT name, imageval 
      FROM sys.stats AS s
      INNER JOIN sys.sysobjvalues AS o
      ON s.object_id = o.objid
      AND s.stats_id = o.subobjid
    WHERE 
      s.object_id = OBJECT_ID('dbo.foo');

Noterai che imagevalper ogni oggetto stats non è uguale al BLOB delle statistiche, ma contiene il BLOB delle statistiche: è solo sfalsato. Sul mio sistema ha prodotto questo per x (ovviamente ho troncato un bel po 'di bit):

0x0100...bunch of chars...000007000000C4E1BE00EEA0...rest the same
                            0x07000000C4E1BE00EEA0...rest the same

E questo per y:

0x0100...bunch of chars...430007000000C7E1BE00EEA0...rest the same
                            0x07000000C7E1BE00EEA0...rest the same

Lo stesso valeva per le statistiche basate sull'indice.

Probabilmente potresti fare un'ulteriore convalida di questo con una serie di query usando i DBCCcomandi. Innanzitutto, individua le pagine interessate dall'indice cluster su sys.sysobjvalues(sostituisci il nome del tuo database):

DBCC IND('splunge', 'sys.sysobjvalues', 1);

Il risultato elencherà un sacco di pagine di cui sei interessato PageType = 1. Con un nuovo database, dovresti essere in grado di trovare queste informazioni su una delle pagine con i PagePIDvalori più alti. Ad esempio sul mio sistema questa era la pagina 281, quindi ho guardato più da vicino a quella pagina:

DBCC TRACEON(3604);

DECLARE @dbid INT = DB_ID();

DBCC PAGE(@dbid, 1, 281, 3);

DBCC TRACEOFF(3604);

Abbastanza sicuro, ho trovato i dati nello slot 17:

Risultati parziali della pagina DBCC

(Su database più grandi, potresti dover fare molto di più a caccia e beccare, dal momento che non c'è garanzia che anche un nuovo oggetto stats finirà in una nuova pagina (er).)

Vai avanti e prova questo a casa, ma c'è un motivo per cui devi connetterti con il DAC per questo. Sarei curioso di sapere, ovviamente, cosa farai con queste informazioni che non potresti fare con l' DBCC SHOW_STATISTICSoutput.

Si noti che questo ovviamente non tenta di decodificare il file STATS_STREAMper fornire istogramma o altre informazioni, e non sono riuscito a trovare alcuna prova che l'output tabulare di DBCC SHOW_STATISTICS ... WITH HISTOGRAMsia archiviato ovunque nel formato tabella. Joe Chang ha alcune informazioni sulla decodifica se è quello che stai cercando. Non credo sia qualcosa che vorresti fare in una query: basta usare DBCC.


2
Abbiamo un vincitore signore e signori. Mi tolgo il cappello, signore.
Zane,

Hahaha, complimenti e grazie, signore! Non ti preoccupare, non sto facendo nulla che non dovrei (AKA "stupido"). È solo per la crescita personale. Mi sono davvero interessato ad esso una volta che mi sono reso conto di non poter trovare nulla al riguardo da nessuna parte. =)
ivanmp,

A proposito dell'articolo di Joe Chang, l'ho trovato mentre cercavo la risposta a questo. Avevo già iniziato a leggerlo. Grazie ancora. :)
ivanmp,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.