Где статистика физически хранится в SQL Server?

27

Где статистика, используемая оптимизатором запросов, физически хранится в файле базы данных SQL Server и в пуле буферов?

Более конкретно, есть ли способ выяснить страницы, используемые статистикой, используя DMV и / или DBCC?

У меня есть книги по внутренним компонентам и SQL Server 2008 Internals, а также по SQL Server Internals и устранению неполадок, и ни одна из них не говорит о физической структуре статистики; если они это сделают, я не смогу найти эту информацию.

ivanmp
источник
1
Когда вы создаете копию базы данных только для статистики, она показывает двоичный файл, который STATS_STREAMя никогда не изучал, находится ли это в самом файле.
Мартин Смит
2
Статистика создается агрегатной функцией только для внутреннего использования ( StatMan), которая выводит большой двоичный объект (по иронии судьбы, это имя выделяется как функция в окне запроса SSMS). Логически, статистика связана с индексом или набором столбцов таблицы, поэтому я бы начал с изучения внутренних таблиц метаданных в поисках столбца binaryили varbinary, который приведет к BLOB-объекту. Это должно быть доступно для просмотра DBCC PAGE, но, вероятно, никак иначе, потому что все это внутреннее.
Джон Зигель
1
@ivanmp Я отредактировал ваш вопрос для ясности, так как многие из более начинающих администраторов баз данных не будут знать, что такое BP или QO.
Макс Вернон
2
Раньше был, sysindexes.statblobно с 2005 года, который возвращается, NULLи местоположение полностью недокументировано, только извлекаемое (что я знаю) до конца DBCC SHOW_STATISTICS(o, i) WITH STATS_STREAM;.
Аарон Бертран
1
Нашел статистику индекса - они есть sys.sysidxstats- похоже, в этой таблице есть указатель большого объекта. Я не уверен, где находится статистика по столбцам; они могут быть в этой таблице, а также есть 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 Page

(В больших базах данных вам, возможно, придется выполнять гораздо больше операций поиска и клевания, поскольку нет гарантии, что даже новый объект статистики попадет на новую (er) страницу.)

Попробуйте это дома, но есть причина, по которой вам нужно подключиться к ЦАП. Мне, конечно, было бы интересно узнать, что вы собираетесь делать с этой информацией, которую вы не можете сделать с DBCC SHOW_STATISTICSвыводом.

Обратите внимание, что это, конечно, не пытается декодировать, STATS_STREAMчтобы предоставить гистограмму или другую информацию, и я не смог найти никаких доказательств того, что табличный вывод DBCC SHOW_STATISTICS ... WITH HISTOGRAMхранится где-либо в табличном формате. У Джо Чанга есть некоторая информация о декодировании, если это то, что вам нужно. Я не думаю, что это то, что вы хотели бы сделать в запросе - просто используйте DBCC.

Аарон Бертран
источник
2
У нас есть победители, дамы и господа. Я снимаю шляпу перед вами, сэр.
Зейн
Хахаха, поздравляю и спасибо, сэр! Не волнуйтесь, я не делаю ничего, что не должен (ака "глупый"). Это просто для личного роста. Я действительно заинтересовался этим, как только понял, что ничего не могу найти об этом нигде. =)
ivanmp
Что касается статьи Джо Чанга, я нашел ее, пока искал ответ на этот вопрос. Я уже начал читать это. Еще раз спасибо. :)
ivanmp