Де фізично зберігаються статистичні дані на SQL сервері?


27

Де статистичні дані, використовувані Оптимізатором запитів, фізично зберігаються у файлі бази даних SQL Server та в буферному пулі?

Більш конкретно, чи є спосіб визначити сторінки, що використовуються статистикою, використовуючи DMV та / або DBCC?

Я володію і внутрішніми службами SQL Server 2008, і внутрішніми та усуненнями неполадок SQL Server, і жодна з них не говорить про фізичну структуру статистики; якщо вони є, я не зможу знайти цю інформацію.


1
Коли ви створюєте лише копію бази даних зі статистичними даними, вона показує двійковий файл, який STATS_STREAMя ніколи не розглядав, чи є це щось виправдане у самому файлі.
Мартін Сміт

2
Статистика створюється за допомогою внутрішньої сукупної функції ( StatMan), яка видає крапку (за іронією долі, це ім'я виділяється як функція у вікні запитів SSMS). За логікою, статистика пов'язана з індексом або набором стовпців таблиць, тому я б почав з вивчення внутрішніх таблиць метаданих, шукаючи binaryабо varbinaryстовпчик, який призведе до краплі. Це слід переглядати, використовуючи DBCC PAGE, але, мабуть, не будь-який інший спосіб, оскільки це все внутрішнє.
Джон Сейгель

1
@ivanmp Я відредагував ваше запитання для наочності, оскільки багато хто з початківців DBA не знатиме, що таке ВР чи КВ.
Макс Вернон

2
Раніше був, sysindexes.statblobале з 2005 року повертається, NULLі місце розташування є повністю недокументованим, його можна отримати лише через те, що я знаю DBCC SHOW_STATISTICS(o, i) WITH STATS_STREAM;.
Аарон Бертран

1
Знайдено статистику індексу - вони є sys.sysidxstats- схоже, що в цій таблиці є вказівник LOB. Я не впевнений, де ще є статистика стовпців; вони можуть бути в цій таблиці, а також typeстовпці.
Джон Сейгель

Відповіді:


30

Знайшов їх.

  1. Створіть таблицю з простим об’єктом статистики.

    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. Підключіться за допомогою ЦАП ( ADMIN:Server[\instance]).

  3. Виконайте такі запити:

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

Ви зауважите, що imagevalдля кожного об'єкта статистики не те саме, що блоб статистики, але він містить блог статистики - це просто зміщення. У моїй системі це дало це для x (я, очевидно, урізав неабиякий біт):

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

І це для у:

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

Те саме стосувалося статистики на основі індексу.

Можливо, ви могли б зробити подальшу перевірку цього за допомогою ряду запитів за допомогою DBCCкоманд. Спочатку з’ясуйте сторінки, які пов’язані з кластерним індексом на sys.sysobjvalues(замініть ім’я вашої бази даних):

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

В результаті буде перераховано купу сторінок, які вас цікавлять PageType = 1. З новою базою даних ви зможете знайти цю інформацію на одній із сторінок з найвищими PagePIDзначеннями. Наприклад, у моїй системі це була сторінка 281, тож я придивився до цієї сторінки:

DBCC TRACEON(3604);

DECLARE @dbid INT = DB_ID();

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

DBCC TRACEOFF(3604);

Звичайно, я знайшов дані в слоті 17:

Часткові результати Сторінки DBCC

(На великих базах даних вам, можливо, доведеться зробити набагато більше полювання та клювання, оскільки немає гарантії, що навіть новий об’єкт статистики опиниться на новій (ер) сторінці.)

Вперед і спробуйте це вдома, але для цього вам потрібно зв’язатися з ЦАП. Мені було б цікаво дізнатись, звичайно, що ви збираєтеся робити з цією інформацією, яку ви не могли зробити з DBCC SHOW_STATISTICSрезультатами.

Зауважте, що це, звичайно, не намагається розшифрувати STATS_STREAMдля надання гістограми чи іншої інформації, і я не міг знайти жодних доказів того, що табличний вихід DBCC SHOW_STATISTICS ... WITH HISTOGRAMзберігається в будь-якому місці у форматі таблиці. Джо Чанг має деяку інформацію про розшифровку, якщо це те, що ви хочете. Я не думаю, що це щось, що ви хочете зробити в запиті - просто використовуйте DBCC.


2
У нас є пані-переможці та панове. Я накидаю вам шапку, сер.
Зейн

Ха-ха-ха, вітаю і дякую, сер! Не хвилюйтеся, я не роблю нічого, чого не повинен (AKA "дурний"). Це просто для особистого зростання. Мене це дуже зацікавило, як тільки я зрозумів, що нічого не можу знайти про це ніде. =)
ivanmp

Щодо статті Джо Чанга, я знайшов це, поки шукав відповідь на це. Я вже почав це читати. Знову дякую. :)
ivanmp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.