Di mana statistik disimpan secara fisik di SQL Server?

27

Di mana statistik yang digunakan oleh Pengoptimal Kueri disimpan secara fisik di dalam file database SQL Server dan Buffer Pool?

Lebih khusus lagi, apakah ada cara untuk mencari tahu halaman yang digunakan oleh statistik menggunakan DMV dan / atau DBCC?

Saya memiliki SQL Server 2008 Internal dan SQL Server Internal dan buku Pemecahan Masalah dan tidak ada yang berbicara tentang struktur fisik statistik; jika mereka melakukannya saya belum dapat menemukan informasi ini.

ivanmp
sumber
1
Ketika Anda membuat hanya statistik salinan dari database itu menunjukkan biner, STATS_STREAMsaya tidak pernah melihat apakah ini adalah sesuatu yang dapat ditemukan dalam file itu sendiri.
Martin Smith
2
Stat dibuat oleh fungsi agregat khusus-saja ( StatMan) yang menampilkan gumpalan (ironisnya, nama itu disorot sebagai fungsi di jendela permintaan SSMS). Secara logis, statistik dikaitkan dengan indeks atau seperangkat kolom tabel, jadi saya akan mulai dengan memeriksa tabel metadata internal mencari binaryatau varbinarykolom yang akan mengarah ke gumpalan. Ini harus dapat dilihat menggunakan DBCC PAGE, tetapi mungkin tidak dengan cara lain karena semuanya internal.
Jon Seigel
1
@ivanmp Saya mengedit pertanyaan Anda untuk kejelasan karena banyak dari DBA yang lebih baru tidak akan tahu apa BP atau QO itu.
Max Vernon
2
Dulu sysindexes.statblobtetapi sejak 2005 yang kembali NULLdan lokasi benar-benar tidak berdokumen, hanya dapat diambil (yang saya tahu) melalui DBCC SHOW_STATISTICS(o, i) WITH STATS_STREAM;.
Aaron Bertrand
1
Menemukan statistik indeks - mereka ada di sys.sysidxstats- sepertinya ada LOB pointer di tabel itu. Saya tidak yakin di mana statistik kolom belum; mereka bisa berada di tabel itu juga ada typekolom.
Jon Seigel

Jawaban:

30

Menemukan mereka

  1. Buat tabel dengan objek statistik sederhana.

    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. Hubungkan menggunakan DAC ( ADMIN:Server[\instance]).

  3. Jalankan pertanyaan berikut:

    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');

Anda akan mencatat bahwa imagevaluntuk setiap objek statistik tidak sama dengan gumpalan stats, tetapi itu berisi gumpalan stats - itu hanya offset. Pada sistem saya ini menghasilkan ini untuk x (saya jelas terpotong sedikit bit):

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

Dan ini untukmu:

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

Hal yang sama berlaku untuk statistik berbasis indeks.

Anda mungkin bisa melakukan validasi lebih lanjut dengan serangkaian pertanyaan menggunakan DBCCperintah. Pertama, cari halaman yang terlibat dengan indeks berkerumun di sys.sysobjvalues(gantilah nama basis data Anda):

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

Hasilnya akan mencantumkan banyak halaman, Anda tertarik pada halaman PageType = 1. Dengan database baru, Anda harus dapat menemukan info ini di salah satu halaman dengan nilai tertinggi PagePID. Misalnya pada sistem saya ini halaman 281, jadi saya melihat lebih dekat ke halaman itu:

DBCC TRACEON(3604);

DECLARE @dbid INT = DB_ID();

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

DBCC TRACEOFF(3604);

Benar saja, saya menemukan data di slot 17:

Sebagian hasil Halaman DBCC

(Pada basis data yang lebih besar, Anda mungkin harus melakukan lebih banyak perburuan dan mematuk, karena tidak ada jaminan bahwa objek statistik baru akan berakhir pada halaman (er) baru.)

Silakan dan coba ini di rumah, tetapi ada alasan Anda perlu terhubung dengan DAC untuk ini. Saya ingin tahu, tentu saja, apa yang akan Anda lakukan dengan informasi ini yang tidak dapat Anda lakukanDBCC SHOW_STATISTICS output.

Perhatikan bahwa ini tentu saja tidak mencoba untuk memecahkan kode STATS_STREAMuntuk memberikan histogram atau informasi lainnya, dan saya tidak dapat menemukan bukti bahwa output tabular DBCC SHOW_STATISTICS ... WITH HISTOGRAMdisimpan di mana saja dalam format tabel. Joe Chang memiliki beberapa informasi tentang decoding jika itu yang Anda cari. Saya tidak berpikir itu adalah sesuatu yang ingin Anda lakukan dalam permintaan - cukup gunakan DBCC.

Aaron Bertrand
sumber
2
Kami memiliki wanita dan pria pemenang. Aku memberi topiku topimu pak.
Zane
Hahaha, selamat dan terima kasih, tuan! Jangan khawatir, saya tidak melakukan apa pun yang seharusnya tidak saya lakukan (AKA "bodoh"). Ini hanya untuk pertumbuhan pribadi. Saya benar-benar tertarik ketika saya menyadari bahwa saya tidak dapat menemukan apa pun tentang ini di mana pun. =)
ivanmp
Tentang artikel Joe Chang, saya menemukannya ketika saya mencari jawaban untuk ini. Saya sudah mulai membacanya. Terima kasih lagi. :)
ivanmp