통계는 SQL Server에서 실제로 어디에 저장됩니까?


27

Query Optimizer가 사용하는 통계는 SQL Server 데이터베이스 파일 및 버퍼 풀 내부에 실제로 저장되는 위치는 어디입니까?

보다 구체적으로, DMV 및 / 또는 DBCC를 사용하여 통계에 사용되는 페이지를 파악할 수있는 방법이 있습니까?

저는 SQL Server 2008 내부 및 SQL Server 내부 및 문제 해결 서적을 모두 보유하고 있으며 통계의 물리적 구조에 대해서는 언급하지 않습니다. 그들이 할 경우이 정보를 찾을 수 없었습니다.


1
데이터베이스의 통계 사본 만 생성하면 바이너리가 표시 STATS_STREAM되므로 파일 자체에서 찾을 수 있는지 여부를 조사한 적이 없습니다.
Martin Smith

2
통계는 StatMan블롭을 출력 하는 내부 전용 집계 함수 ( )에 의해 생성됩니다 (아이 론적으로 해당 이름은 SSMS 쿼리 창에서 함수로 강조 표시됨). 논리적으로 통계는 인덱스 또는 테이블 열 집합과 관련되어 있으므로 내부 메타 데이터 테이블을 검사 하여 블롭으로 이어질 열 binary또는 varbinary열을 찾습니다 . 이것은을 사용하여 볼 수 있어야 DBCC PAGE하지만 모두 내부이기 때문에 다른 방법 으로는 볼 수 없습니다.
Jon Seigel

1
@ivanmp 나는 많은 초보자 DBA가 BP 또는 QO가 무엇인지 알지 못하므로 명확성을 위해 귀하의 질문을 편집했습니다.
Max Vernon

2
에서로 사용 sysindexes.statblob하지만, 2005 년 이후 반환 NULL및 위치가 완전히 문서화되지 않은 통해 (내가 아는)만을 검색 할 DBCC SHOW_STATISTICS(o, i) WITH STATS_STREAM;.
Aaron Bertrand

1
인덱스 통계를 찾았습니다.이 통계 sys.sysidxstats는 해당 테이블에 LOB 포인터가있는 것 같습니다. 열 통계가 아직 어디에 있는지 잘 모르겠습니다. 그들은 type열 뿐만 아니라 그 테이블에있을 수 있습니다 .
Jon Seigel

답변:


30

찾았어요

  1. 간단한 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. DAC ( 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

그리고 이것은 y의 경우 :

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 페이지의 일부 결과

(대규모 데이터베이스의 경우 새로운 통계 개체조차도 새로운 페이지에 끝날 것이라는 보장이 없기 때문에 더 많은 사냥과 펙킹을 수행해야 할 수도 있습니다.)

계속해서 집에서 시도해보십시오. 그러나이를 위해 DAC와 연결해야하는 이유가 있습니다. 물론 DBCC SHOW_STATISTICS출력으로 할 수 없었던이 정보로 무엇을 할 것인지 궁금합니다 .

물론 이것은 STATS_STREAM히스토그램이나 다른 정보를 제공하기 위해 를 해독하려고 시도하지 않으며 표 형식의 출력이 DBCC SHOW_STATISTICS ... WITH HISTOGRAM테이블 형식으로 어디에 저장되어 있는지에 대한 증거를 찾을 수 없었습니다 . Joe Chang은 당신이 좋아하는 디코딩에 대한 정보를 가지고 있습니다. 나는 그것이 당신이 쿼리에서하고 싶은 것이라고 생각하지 않습니다-그냥 사용하십시오 DBCC.


2
우리는 승자 신사 숙녀 여러분이 있습니다. 나는 당신에게 내 모자를 팁.
Zane

하하, 축하합니다. 감사합니다! 걱정하지 마십시오. 내가하지 말아야 할 일을하지 않습니다 (일명 "멍청한"). 그것은 단지 개인적인 성장을위한 것입니다. 나는 이것에 대해 아무것도 찾을 수 없다는 것을 깨달았을 때 그것에 정말로 관심이있었습니다. =)
ivanmp

Joe Chang의 기사에 대해, 나는 이것에 대한 답을 찾고있는 동안 그것을 찾았습니다. 나는 이미 그것을 읽기 시작했다. 다시 감사합니다. :)
ivanmp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.