통계에서 히스토그램 단계의 수는 어떻게 결정됩니까?


11

SQL Server의 통계에서 히스토그램 단계 수는 어떻게 결정됩니까?

키 열에 200 개 이상의 고유 값이 있어도 왜 200 단계로 제한됩니까? 결정 요인이 있습니까?


데모

스키마 정의

CREATE TABLE histogram_step
  (
     id   INT IDENTITY(1, 1),
     name VARCHAR(50),
     CONSTRAINT pk_histogram_step PRIMARY KEY (id)
  )

내 테이블에 100 개의 레코드 삽입

INSERT INTO histogram_step
            (name)
SELECT TOP 100 name
FROM   sys.syscolumns

통계 업데이트 및 확인

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step)

히스토그램 단계 :

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|            3 |          1 |       1 |                   1 |              1 |
|            5 |          1 |       1 |                   1 |              1 |
|            7 |          1 |       1 |                   1 |              1 |
|            9 |          1 |       1 |                   1 |              1 |
|           11 |          1 |       1 |                   1 |              1 |
|           13 |          1 |       1 |                   1 |              1 |
|           15 |          1 |       1 |                   1 |              1 |
|           17 |          1 |       1 |                   1 |              1 |
|           19 |          1 |       1 |                   1 |              1 |
|           21 |          1 |       1 |                   1 |              1 |
|           23 |          1 |       1 |                   1 |              1 |
|           25 |          1 |       1 |                   1 |              1 |
|           27 |          1 |       1 |                   1 |              1 |
|           29 |          1 |       1 |                   1 |              1 |
|           31 |          1 |       1 |                   1 |              1 |
|           33 |          1 |       1 |                   1 |              1 |
|           35 |          1 |       1 |                   1 |              1 |
|           37 |          1 |       1 |                   1 |              1 |
|           39 |          1 |       1 |                   1 |              1 |
|           41 |          1 |       1 |                   1 |              1 |
|           43 |          1 |       1 |                   1 |              1 |
|           45 |          1 |       1 |                   1 |              1 |
|           47 |          1 |       1 |                   1 |              1 |
|           49 |          1 |       1 |                   1 |              1 |
|           51 |          1 |       1 |                   1 |              1 |
|           53 |          1 |       1 |                   1 |              1 |
|           55 |          1 |       1 |                   1 |              1 |
|           57 |          1 |       1 |                   1 |              1 |
|           59 |          1 |       1 |                   1 |              1 |
|           61 |          1 |       1 |                   1 |              1 |
|           63 |          1 |       1 |                   1 |              1 |
|           65 |          1 |       1 |                   1 |              1 |
|           67 |          1 |       1 |                   1 |              1 |
|           69 |          1 |       1 |                   1 |              1 |
|           71 |          1 |       1 |                   1 |              1 |
|           73 |          1 |       1 |                   1 |              1 |
|           75 |          1 |       1 |                   1 |              1 |
|           77 |          1 |       1 |                   1 |              1 |
|           79 |          1 |       1 |                   1 |              1 |
|           81 |          1 |       1 |                   1 |              1 |
|           83 |          1 |       1 |                   1 |              1 |
|           85 |          1 |       1 |                   1 |              1 |
|           87 |          1 |       1 |                   1 |              1 |
|           89 |          1 |       1 |                   1 |              1 |
|           91 |          1 |       1 |                   1 |              1 |
|           93 |          1 |       1 |                   1 |              1 |
|           95 |          1 |       1 |                   1 |              1 |
|           97 |          1 |       1 |                   1 |              1 |
|           99 |          1 |       1 |                   1 |              1 |
|          100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

우리가 볼 수 있듯이 히스토그램에는 53 단계가 있습니다.

수천 개의 레코드를 다시 삽입

INSERT INTO histogram_step
            (name)
SELECT TOP 10000 b.name
FROM   sys.syscolumns a
       CROSS JOIN sys.syscolumns b

통계 업데이트 및 확인

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step)

이제 히스토그램 단계가 4 단계로 줄었습니다.

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|        10088 |      10086 |       1 |               10086 |              1 |
|        10099 |         10 |       1 |                  10 |              1 |
|        10100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

수천 개의 레코드를 다시 삽입

INSERT INTO histogram_step
            (name)
SELECT TOP 100000 b.name
FROM   sys.syscolumns a
       CROSS JOIN sys.syscolumns b

통계 업데이트 및 확인

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step) 

이제 히스토그램 단계가 3 단계로 줄었습니다.

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|       110099 |     110097 |       1 |              110097 |              1 |
|       110100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

이 단계가 어떻게 결정되는지 누군가가 말해 줄 수 있습니까?


3
200은 임의의 선택이었습니다. 특정 테이블에 몇 개의 고유 값이 있는지와는 관련이 없습니다. 200을 선택한 이유를 알고 싶다면 동료가 아닌 1990 년대 SQL Server 팀의 엔지니어에게 문의해야합니다.
Aaron Bertrand

1
@AaronBertrand-고맙습니다 .. 어떻게이 단계들이 결정
되었는가

1
결정이 없습니다. 상한은 200입니다. 기간. 기술적으로는 201 년이지만 그것은 또 다른 하루의 이야기입니다.
Aaron Bertrand

1
나는 단계 내 추정에 대해 비슷한 질문을 했는데
jesijesi

답변:


14

이 게시물은 단일 열 통계에 대해 논의하는 것으로 제한 할 것입니다. 이미 열이 길고 SQL Server가 데이터를 히스토그램 단계로 버킷하는 방법에 관심이 있기 때문입니다. 다중 컬럼 통계의 경우 히스토그램은 선행 컬럼에서만 작성됩니다.

SQL Server는 통계 업데이트가 필요하다고 판단하면 모든 테이블 데이터 또는 테이블 데이터 샘플을 읽는 숨겨진 쿼리를 시작합니다. 확장 된 이벤트가있는 이러한 쿼리를 볼 수 있습니다. StatMan히스토그램 생성과 관련된 SQL Server 내에 함수가 있습니다 . 간단한 통계 개체의 경우 최소 두 가지 유형의 StatMan쿼리가 있습니다 (빠른 통계 업데이트에 대한 다른 쿼리가 있으며 파티션 된 테이블의 증분 통계 기능도 다른 쿼리를 사용하는 것 같습니다).

첫 번째는 필터링하지 않고 테이블의 모든 데이터를 가져옵니다. 테이블이 매우 작거나 FULLSCAN옵션을 사용하여 통계를 수집 할 때이를 확인할 수 있습니다 .

CREATE TABLE X_SHOW_ME_STATMAN (N INT);
CREATE STATISTICS X_STAT_X_SHOW_ME_STATMAN ON X_SHOW_ME_STATMAN (N);

-- after gathering stats with 1 row in table
SELECT StatMan([SC0]) FROM
(
    SELECT TOP 100 PERCENT [N] AS [SC0] 
    FROM [dbo].[X_SHOW_ME_STATMAN] WITH (READUNCOMMITTED)
    ORDER BY [SC0] 
) AS _MS_UPDSTATS_TBL 
OPTION (MAXDOP 16);

SQL Server는 테이블 크기에 따라 자동 샘플 크기를 선택합니다 (테이블의 행 수와 페이지 수라고 생각합니다). 테이블이 너무 크면 자동 샘플 크기가 100 % 아래로 떨어집니다. 1M 행의 동일한 테이블에 대해 얻은 내용은 다음과 같습니다.

-- after gathering stats with 1 M rows in table
SELECT StatMan([SC0], [SB0000]) FROM 
(
    SELECT TOP 100 PERCENT [SC0], step_direction([SC0]) over (order by NULL) AS [SB0000] 
    FROM 
    (
        SELECT [N] AS [SC0] 
        FROM [dbo].[X_SHOW_ME_STATMAN] TABLESAMPLE SYSTEM (6.666667e+001 PERCENT) WITH (READUNCOMMITTED) 
    ) AS _MS_UPDSTATS_TBL_HELPER 
    ORDER BY [SC0], [SB0000] 
) AS _MS_UPDSTATS_TBL
OPTION (MAXDOP 1);

TABLESAMPLE되고 문서화 하지만 StatMan 및 step_direction는 없습니다. 여기서 SQL Server는 히스토그램을 만들기 위해 테이블에서 약 66.6 %의 데이터를 샘플링합니다. 이것이 의미하는 바는 FULLSCAN동일한 데이터에서 통계를 업데이트 할 때 다른 수의 히스토그램 단계를 얻을 수 있다는 것 입니다. 나는 이것을 실제로 관찰 한 적이 없지만 왜 그것이 불가능할지는 알지 못한다.

간단한 데이터에 대한 몇 가지 테스트를 실행하여 시간에 따른 통계 변화를 확인하십시오. 아래는 순차 정수를 테이블에 삽입하고 각 삽입 후 통계를 수집하고 통계에 대한 정보를 결과 테이블에 저장하기 위해 작성한 일부 테스트 코드입니다. 한 번에 한 행을 최대 10000까지 삽입하는 것으로 시작하겠습니다. 테스트 베드 :

DECLARE
@stats_id INT,
@table_object_id INT,
@rows_per_loop INT = 1,
@num_of_loops INT = 10000,
@loop_num INT;

BEGIN
    SET NOCOUNT ON;

    TRUNCATE TABLE X_STATS_RESULTS;

    SET @table_object_id = OBJECT_ID ('X_SEQ_NUM');
    SELECT @stats_id = stats_id FROM sys.stats
    WHERE OBJECT_ID = @table_object_id
    AND name = 'X_STATS_SEQ_INT_FULL';

    SET @loop_num = 0;
    WHILE @loop_num < @num_of_loops
    BEGIN
        SET @loop_num = @loop_num + 1;

        INSERT INTO X_SEQ_NUM WITH (TABLOCK)
        SELECT @rows_per_loop * (@loop_num - 1) + N FROM dbo.GetNums(@rows_per_loop);

        UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN; -- can comment out FULLSCAN as needed

        INSERT INTO X_STATS_RESULTS WITH (TABLOCK)
        SELECT 'X_STATS_SEQ_INT_FULL', @rows_per_loop * @loop_num, rows_sampled, steps 
        FROM sys.dm_db_stats_properties(@table_object_id, @stats_id);
        END;
END;

이 데이터의 경우 히스토그램 단계 수가 200으로 빠르게 증가하고 (처음에는 397 행으로 최대 단계 수에 도달 함) 1485 행이 테이블에있을 때까지 199 또는 200으로 유지 된 다음 막대 그래프가 3 또는 4 만 될 때까지 천천히 감소합니다. 단계. 다음은 모든 데이터의 그래프입니다.

첫 번째 그래프

히스토그램은 10k 행에 대한 모양입니다.

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           1       0                   1
9999            9997        1       9997                1
10000           0           1       0                   1

히스토그램에 3 단계 만있는 것이 문제입니까? 정보가 우리의 관점에서 보존 된 것처럼 보입니다. 데이터 유형이 INTEGER이므로 1에서 10000 사이의 각 정수에 대해 테이블에 몇 개의 행이 있는지 알아낼 수 있습니다. 일반적으로 SQL Server는이를 파악할 수 있지만 일부는 제대로 작동하지 않습니다. . 이에 대한 예는 이 SE 게시물 을 참조하십시오 .

테이블에서 단일 행을 삭제하고 통계를 업데이트하면 어떻게 될까요? 이상적으로 우리는 누락 된 정수가 더 이상 테이블에 없다는 것을 보여주는 또 다른 히스토그램 단계를 얻게됩니다.

DELETE FROM X_SEQ_NUM
WHERE X_NUM  = 1000;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 3 steps

DELETE FROM X_SEQ_NUM
WHERE X_NUM  IN (2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 3 steps

조금 실망 스럽습니다. 히스토그램을 직접 작성하는 경우 각 결 측값에 대한 단계를 추가합니다. SQL Server는 범용 알고리즘을 사용하므로 일부 데이터 세트의 경우 사용하는 코드보다 더 적합한 히스토그램을 얻을 수 있습니다. 물론, 테이블에서 0 또는 1 행을 얻는 것의 실질적인 차이는 매우 작습니다. 20000 행으로 테스트 할 때 각 정수에 2 개의 행이있는 동일한 결과를 얻습니다. 데이터를 삭제할 때 히스토그램이 단계를 얻지 못합니다.

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           2       0                   1
9999            19994       2       9997                2
10000           0           2       0                   1

테이블에 100 개의 행이있는 각 정수로 백만 개의 행으로 테스트하면 약간 더 나은 결과를 얻을 수 있지만 여전히 더 좋은 히스토그램을 만들 수 있습니다.

truncate table X_SEQ_NUM;

BEGIN TRANSACTION;
INSERT INTO X_SEQ_NUM WITH (TABLOCK)
SELECT N FROM dbo.GetNums(10000);
GO 100
COMMIT TRANSACTION;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- 4 steps

DELETE FROM X_SEQ_NUM
WHERE X_NUM  = 1000;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- now 5 steps with a RANGE_HI_KEY of 998 (?)

DELETE FROM X_SEQ_NUM
WHERE X_NUM  IN (2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 5 steps

최종 히스토그램 :

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           100     0                   1
998             99600       100     996                 100
3983            298100      100     2981                100
9999            600900      100     6009                100
10000           0           100     0                   1

순차적 인 정수로 더 테스트하지만 테이블에 더 많은 행이 있습니다. 테이블 크기를 수동으로 지정하는 것이 너무 작은 테이블의 경우에는 효과가 없으므로 각 삽입에 100 개의 행을 추가하고 최대 백만 개의 행마다 통계를 수집합니다. 테이블에서 637300 개의 행에 도달하면 더 이상 기본 샘플 속도로 테이블의 행을 100 % 샘플링하지 않는 것을 제외하고는 이전과 비슷한 패턴이 표시됩니다. 행을 얻으면 히스토그램 단계 수가 증가합니다. 테이블의 샘플링되지 않은 행 수가 증가함에 따라 SQL Server가 데이터에 더 많은 간격을두기 때문일 수 있습니다. 1M 행에서도 200 단계를 치지 않지만 행을 계속 추가하면 거기에 도착하여 결국 다시 내려갈 것으로 예상됩니다.

그래프 2

X 축은 테이블의 행 수입니다. 행 수가 증가함에 따라 샘플링 된 행은 조금씩 다르며 650k를 넘지 않습니다.

이제 VARCHAR 데이터로 간단한 테스트를 해보자.

CREATE TABLE X_SEQ_STR (X_STR VARCHAR(5));
CREATE STATISTICS X_SEQ_STR ON X_SEQ_STR(X_STR);

여기에 NULL과 함께 200 개의 숫자 (문자열)를 삽입하고 있습니다.

INSERT INTO X_SEQ_STR
SELECT N FROM dbo.GetNums(200)
UNION ALL
SELECT NULL;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 111 steps, RANGE_ROWS is 0 or 1 for all steps

NULL은 테이블에서 발견 될 때 항상 자체 히스토그램 단계를 얻습니다. SQL Server는 모든 정보를 보존하기 위해 정확히 201 단계를 제공 할 수 있었지만 그렇게하지 않았습니다. 예를 들어 '1111'이 '1'과 '2'사이에서 정렬되므로 기술적으로 정보가 손실됩니다.

이제 정수 대신 다른 문자를 삽입 해 봅시다.

truncate table X_SEQ_STR;

INSERT INTO X_SEQ_STR
SELECT CHAR(10 + N) FROM dbo.GetNums(200)
UNION ALL
SELECT NULL;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 95 steps, RANGE_ROWS is 0 or 1 or 2

마지막 테스트와 실제로 차이가 없습니다.

이제 문자를 삽입하고 표에 각 문자의 다른 수를 입력 해 봅시다. 예를 들어 CHAR(11)1 행, CHAR(12)2 행 등이 있습니다.

truncate table X_SEQ_STR;

DECLARE
@loop_num INT;

BEGIN
    SET NOCOUNT ON;

    SET @loop_num = 0;
    WHILE @loop_num < 200
    BEGIN
        SET @loop_num = @loop_num + 1;

        INSERT INTO X_SEQ_STR WITH (TABLOCK)
        SELECT CHAR(10 + @loop_num) FROM dbo.GetNums(@loop_num);
    END;
END;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 148 steps, most with RANGE_ROWS of 0

이전과 마찬가지로 여전히 200 히스토그램 단계를 얻지 못합니다. 그러나 많은 단계는 RANGE_ROWS0입니다.

최종 테스트를 위해 각 루프에 임의의 5 자 문자열을 삽입하고 매번 통계를 수집합니다. 다음은 임의의 문자열 코드입니다.

char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))

다음은 표 대 막대 그래프 단계의 행 그래프입니다. 그래프 3

한 단계 씩 올라가고 내려 가기 시작하면 단계 수는 100 아래로 떨어지지 않습니다. SQL Server 히스토그램 구축 알고리즘은 히스토그램 단계를위한 공간이 부족할 때 히스토그램 단계를 결합한다는 것을 들었습니다. 따라서 약간의 데이터를 추가하여 단계 수를 대폭 변경할 수 있습니다. 다음은 내가 찾은 흥미로운 데이터 샘플입니다.

ROWS_IN_TABLE   ROWS_SAMPLED    STEPS
36661           36661           133
36662           36662           143
36663           36663           143
36664           36664           141
36665           36665           138

로 샘플링하더라도 FULLSCAN단일 행을 추가하면 단계 수를 10 씩 늘리고 일정하게 유지 한 다음 2 씩 줄인 다음 3으로 줄입니다.

이 모든 것에서 무엇을 요약 할 수 있습니까? 나는 이것을 증명할 수 없지만, 이러한 관찰은 사실로 보인다.

  • SQL Server는 일반적인 사용 알고리즘을 사용하여 히스토그램을 만듭니다. 일부 데이터 배포의 경우 손으로 데이터를보다 완벽하게 표현할 수 있습니다.
  • 테이블에 NULL 데이터가 있고 통계 쿼리에서 찾은 경우 해당 NULL 데이터는 항상 자체 히스토그램 단계를 가져옵니다.
  • 표에서 찾은 최소값은 RANGE_ROWS= 0 인 자체 히스토그램 단계를 가져옵니다 .
  • 표에서 찾은 최대 값은 표에서 최종 값이됩니다 RANGE_HI_KEY.
  • SQL Server는 더 많은 데이터를 샘플링 할 때 기존 단계를 결합하여 찾은 새 데이터를위한 공간을 만들어야합니다. 충분한 히스토그램을 보면 공통 값이 DISTINCT_RANGE_ROWS또는에 반복되는 것을 볼 수 있습니다 RANGE_ROWS. 예를 들어, 대 시간의 무리 255 개 방송 RANGE_ROWSDISTINCT_RANGE_ROWS현재 파이널 테스트 케이스.
  • 간단한 데이터 배포의 경우 SQL Server가 순차 데이터를 하나의 히스토그램 단계로 결합하여 정보 손실이 발생하지 않는 것을 볼 수 있습니다. 그러나 데이터에 간격을 추가하면 히스토그램이 원하는 방식으로 조정되지 않을 수 있습니다.

이 모든 것이 언제 문제입니까? 쿼리 최적화 프로그램이 올바른 결정을 내릴 수있는 방식으로 데이터 분포를 나타낼 수없는 히스토그램으로 인해 쿼리 성능이 저하 될 때 문제가됩니다. SQL Server가 수백만 행 이상에서 히스토그램을 생성하지만 정확히 200 또는 201 히스토그램 단계를 사용하지 않는 경우 더 많은 히스토그램 단계를 갖는 것이 항상 더 좋다고 생각하고있는 경향이 있다고 생각합니다. 그러나 히스토그램에 200 또는 201 단계가 있어도 많은 통계 문제가 발생했습니다. 통계 개체에 대해 SQL Server가 생성하는 히스토그램 단계 수를 제어 할 수 없으므로 걱정하지 않아도됩니다. 그러나 통계 문제로 인해 쿼리 성능이 저하 될 때 수행 할 수있는 몇 가지 단계가 있습니다. 나는 아주 간단한 개요를 줄 것이다.

통계를 완전히 수집하면 경우에 따라 도움이 될 수 있습니다. 매우 큰 테이블의 경우 자동 샘플 크기는 테이블에있는 행의 1 %보다 작을 수 있습니다. 때로는 열의 데이터 중단에 따라 계획이 잘못 될 수 있습니다. CREATE STATISTICSUPDATE STATISTICS에 대한 Microsoft의 설명서 는 다음과 같이 말합니다.

샘플은 기본 샘플링을 기반으로하는 쿼리 계획이 최적이 아닌 특수한 경우에 유용합니다. 대부분의 상황에서 쿼리 최적화 프로그램은 이미 샘플링을 사용하고 고품질 쿼리 계획을 만드는 데 필요한 통계적으로 중요한 샘플 크기를 결정하기 때문에 SAMPLE을 지정할 필요가 없습니다.

대부분의 워크로드에는 전체 스캔이 필요하지 않으며 기본 샘플링이 적합합니다. 그러나 매우 다양한 데이터 배포에 민감한 특정 워크로드에는 샘플 크기를 늘리거나 전체 스캔을 수행해야 할 수도 있습니다.

필터링 된 통계를 작성하면 도움이 될 수 있습니다. 비대칭 데이터와 많은 다른 고유 값이있는 열이있을 수 있습니다. 데이터에 일반적으로 필터링되는 특정 값이있는 경우 해당 공통 값에 대한 통계 히스토그램을 생성 할 수 있습니다. 쿼리 최적화 프로그램은 모든 열 값에 정의 된 통계 대신 더 작은 범위의 데이터에 정의 된 통계를 사용할 수 있습니다. 여전히 히스토그램에서 200 단계를 보장 할 수는 없지만, 하나의 값으로 필터링 된 통계를 생성하면 해당 값으로 히스토그램 단계가됩니다.

분할 된 뷰를 사용하면 테이블에 대해 200 개 이상의 단계를 효과적으로 얻을 수 있습니다. 큰 테이블을 매년 하나의 테이블로 쉽게 분할 할 수 있다고 가정하십시오. UNION ALL모든 연간 테이블을 결합 하는 보기를 작성합니다 . 각 테이블에는 자체 히스토그램이 있습니다. SQL Server 2014에 도입 된 새로운 증분 통계는 통계 업데이트의 효율성을 높여줍니다. 쿼리 최적화 프로그램은 파티션 당 생성 된 통계를 사용하지 않습니다.

여기서 실행할 수있는 더 많은 테스트가 있으므로 실험 해 보시기 바랍니다. SQL Server 2014 Express 에서이 테스트를 수행 했으므로 실제로 아무것도 막을 수 없습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.