MySQL 통계정보 - 테이블 통계 - 인덱스 통계

Share

Last Updated on 1월 20, 2024 by Jade(정현호)

안녕하세요 
이번 포스팅에서는 MySQL 의 통계정보에 대해서 테이블 통계 와 인덱스 통계 각각에 대해서 확인해보도록 하겠습니다.

해당 포스팅은 Real MySQL 8.0 을 정리한 내용으로 MySQL Document 를 참조한 글입니다

통계 정보

통계정보 는 데이터베이스 마다 고유하게 존재하는 쿼리의 최적화와 실행계획을 작성하는 비용기반의 옵티마이저(Optimizer)가 참조하는 정보로 가장 필수적인 정보입니다.

쿼리의 실행 계획을 최적화하기 위해서는 현재 데이터 저장 상태를 확인할 정보가 필요하며, 이러한 수집된 정보를(통계정보) 토대로 옵티마이저는 최적의 실행계획을 세우게 됩니다.
지금 보통적으로 사용되는 RDS 그리고 보통 많이 사용되는 지금의 버전에서는 옵티마이저는 대부분 비용기반(CBO)를 사용을 하게 되고 그에 따라 통계정보도 매우 중요한 DB 관리요소가 되었습니다.

Note: RBO

오라클의 예전 버전인 9iR2 버전까지는 OPTIMIZER_MODE 의 기본값이 choose 이었으며, 통계정보를 사용할 수 없을 경우 RBO 로 동작하였습니다.

그래서 오라클은 예전 버전인 9iR2 버전까지 RBO 를 사용하는 경우가 있었습니다만 10g 버전부터는 CBO 로 변경되었습니다.


MySQL 서버는 5.7 버전까지 테이블과 인덱스에 대한 개괄적인 정보를 가지고 실행 계획을 수립하였습니다.


하지만 이는 테이블 컬럼의 값들이 실제 어떻게 분포돼 있는지에 대한 정보가 없기 때문에 실행 계획의 정확도가 떨어지는 경우가 많았습니다.
그래서 MySQL 8.0 버전부터는 인덱스가 되지 않은 컬럼에 대해서도 데이터 분포도를 수집해서 저장하는 히스토그램(Histogram) 정보가 추가되었습니다.

히스토그램 이 도입되었다고 해서 기존의 테이블이나 인덱스의 통계 정보가 필요치 않은 것은 아닙니다.
       

비용 기반 최적화

비용 기반 최적화(Cost Based Optimization) 에서 가장 중요한 것은 통계 정보이고, 또한 가급적 정확한 통계정보입니다.
통계정보가 정확하지 않는다면 전혀 다른 방향으로 쿼리가 실행될 수 있기 때문입니다.

예를 들어, 1억 건의 레코드가 저장된 테이블의 통계 정보가 갱신되지 않아서 레코드가 10건 미만인 것처럼 돼 있다면 옵티마이저는 실제 쿼리를 실행할 때 인덱스 레인지 스캔(Index Range Scan)이 아니라 테이블을 처음부터 끝까지 읽는 방식인 풀테이블 스캔(Full Table Scan)으로 실행해 버릴 수도 있기 때문입니다.
이런 부정확한 통계 정보 탓에 0.1초에 끝날 쿼리가 1시간이상 소요가 될 수도 있습니다.

MySQL 또한 다른 DBMS와 같이 비용기반의 최적화를 사용하지만, 다른 DBMS 보다 통계정보의 정확도가 높지 않고 통계 정보의 휘발성이 강하였습니다.
그래서 MySQL 서버에서는 쿼리의 실행 계획을 수립할 때 실제 테이블의 데이터를 일부 분석해서 통계정보를 보완해서 사용하였습니다.

이러한 이유로 MySQL 5.6 버전 부터는 통계 정보의 정확성을 높일 수 있는 방법이 도입되었지만, 아직도 많은 사용자는 기존 방식 그대로 사용을 하고 있습니다.

Note

Oracle 의 경우 갑작스러운 플랜의 변경을 방지하고자 많은 사이트에서 자동 통계정보 수집 기능을 비활성화 하고 사용하고 있습니다.

기본적인 통계정보만을 수집하고 그 외 추가로 통계정보를 수집하지 않고 기존의 통계정보를 그대로 유지하여 사용하는 사이트나 시스템도 많은 편입니다.

그래서 Oracle 에서는 SQL 레벨에서의 Hint 가 주로 많이 사용하여 플랜을 보정하고 고정하여 사용하고 있습니다.

      

테이블 통계 정보

MySQL 5.6 버전 부터는 InnoDB 스토리지 엔진을 사용하는 테이블에 대한 통계 정보를 영구적으로(Persistent) 관리할 수 있게 개선되었습니다. 
MySQL 5.5 버전까지는 각 테이블의 통계 정보가 메모리에서만 관리되었고, SHOW INDEX 명령어로만 테이블의 인덱스 컬럼의 분포도를 확인할 수 있었습니다.

이처럼 통계 정보가 메모리에서 관리될 경우 MySQL 5.5 버전에서 서버가 재시작 되면 지금까지 수집된 통계 정보 모두가 사라지게 됩니다.
그래서 MySQL 5.5 버전에서 서버가 재시작 되면 모든 테이블의 통계정보는 다시 수집되어야 했습니다.

MySQL 5.6 버전부터는 각 테이블의 통계정보를 mysql 데이터베이스(스키마) 의 innodb_index_stats 와 innodb_table_stats 테이블로 관리할 수 있게 개선되었습니다. 이렇게 통계 정보를 테이블로 관리함으로써 MySQL 서버가 재시작되어도 기존의 통계정보를 유지할 수 있게 되었습니다.
이렇게 통계 정보를 테이블로 관리하게 됨에 따라서 MySQL 서버가 재시작 되어도 기존의 통계 정보를 유지할 수 있게 되었습니다.

mysql> use mysql;
Database changed

mysql> show tables like '%_stats';
+---------------------------+
| Tables_in_mysql (%_stats) |
+---------------------------+
| innodb_index_stats        |
| innodb_table_stats        |
+---------------------------+


MySQL 5.6 에서 테이블을 생성할 때는 STATS_PERSISTENT 옵션을 설정할 수 있으며, 이 값에 따라서 테이블 단위로 영구적인 통계 정보를 저장을 할지를 결정하게 됩니다.

mysql> CREATE TABLE tb_test(
id int, 
col varchar(100),
PRIMARY KEY(id))
ENGINE=InnoDB
STATS_PERSISTENT={ DEFAULT | 0 | 1 }


• STATS_PERSISTENT=0
테이블의 통계 정보를 MySQL 5.5 이전의 방식대로 관리하는 것을 의미하며, mysql 데이터베이스의 innodb_index_stats 와 innodb_table_stats 에 저장하지 않게 됩니다.


• STATS_PERSISTENT=1
테이블의 통계 정보를 mysql 데이터베이스의 innodb_index_stats 와 innodb_table_stats 에 저장합니다.


• STATS_PERSISTENT=DEFAULT
테이블을 생성할 때 STATS_PERSISTENT 구문을 생략하게 되면 선택되는 값, 즉 DEFAULT 값으로 innodb_stats_persistent 시스템 변수와 연관되어 있으며 innodb_stats_persistent 설정 값을 따라가게 되고 해당 시스템 변수의 기본값은 ON 입니다.
즉 기본값은 통계정보를 mysql 데이터베이스의 innodb_index_stats 와 innodb_table_stats 에 저장하게 됩니다.

확인해보기 위해서 아래와 같이 STATS_PERSISTENT 값을 달리 하여 테이블을 두 번 생성하여 확인해보았습니다.

-- STATS_PERSISTENT=1 설정
mysql> create table tb_persistent_test (
    id int
 ) ENGINE=InnoDB STATS_PERSISTENT=1;

mysql> select * from mysql.innodb_table_stats
where table_name ='tb_persistent_test'\G

*************************** 1. row ***************************
           database_name: tdb
              table_name: tb_persistent_test
             last_update: 2021-11-13 15:00:00
                  n_rows: 0
    clustered_index_size: 1
sum_of_other_index_sizes: 0
1 row in set (0.00 sec)


-- STATS_PERSISTENT=0 설정
mysql> drop table tb_persistent_test;
mysql> create table tb_persistent_test (
    id int
 ) ENGINE=InnoDB STATS_PERSISTENT=0;

mysql> select * from mysql.innodb_table_stats
where table_name ='tb_persistent_test'\G

Empty set (0.00 sec)


이와 같이 STATS_PERSISTENT 설정에 따라서 통계정보가 테이블에 적재 유무가 달라지는 것을 확인할 수 있습니다.
생성된 테이블은 ALTER 로 STATS_PERSISTENT 속성을 변경할 수 있습니다.

mysql> alter table tb_persistent_test STATS_PERSISTENT=1;

또는

mysql> alter table tb_persistent_test STATS_PERSISTENT=0;


innodb_table_stats 딕셔너리 테이블의 컬럼은 각각 아래와 같은 의미를 담고 있습니다.

database_name : 데이터베이스 네임
table_name : 테이블 이름, 파티션 이름 또는 서브 파티션
last_update : 이 행을 마지막으로 업데이트한 시간을 나타내는 시간
n_rows : 테이블의 전체 레코드 수
clustered_index_size : Primary Key 의 크기(InnoDB 페이지 개수)
sum_of_other_index_sizes : PK를 제외한 인덱스의 크기(InnoDB 페이지 개수)

Note

innodb_table_stats.sum_of_other_index_sizes 값은 테이블의 STATS_AUTO_RECAL 옵션에 따라서 0으로 보일 수 있습니다.

이럴 경우 ANALYZE TABLE 명령어를 사용하면 통계 값이 반영되게 됩니다.

      

인덱스 통계 정보

인덱스의 통계정보는 mysql.innodb_index_stats 에 저장되며 해당 딕셔너리 테이블을 통해 여러 정보를 확인할 수 있습니다.

아래에서 생성하는 예제 테이블은 MySQL Document의 employees-installation 에서 가이드 되고 있는 github 에서 테이블 DDL 구문과 데이터를 다운로드 받을 수 있습니다.


서버에서 github 에 있는 데이터 dump 파일을 직접 다운로드 받겠습니다.

wget https://github.com/datacharmer/test_db/raw/master/load_employees.dump


테이블 생성(데이터 로드까지) 후에 인덱스 통계정보를 확인해보도록 하겠습니다.

-- 테이블 생성(인덱스가 2개더 추가됨)
mysql> CREATE TABLE employees (
    emp_no      INT             NOT NULL,
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,    
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no),
    KEY idx_first_name(first_name),
    KEY idx_hire_date(hire_date)
);


-- 데이터 적재
mysql> source load_employees.dump;


-- mysql.innodb_index_stats 조회
mysql> select * 
from mysql.innodb_index_stats 
where table_name ='employees';

+---------------+------------+----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name | index_name     | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
+---------------+------------+----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| test_db       | employees  | PRIMARY        | 2021-11-13 15:30:00 | n_diff_pfx01 |     299113 |          20 | emp_no                            |
| test_db       | employees  | PRIMARY        | 2021-11-13 15:30:00 | n_leaf_pages |        886 |        NULL | Number of leaf pages in the index |
| test_db       | employees  | PRIMARY        | 2021-11-13 15:30:00 | size         |       1057 |        NULL | Number of pages in the index      |
| test_db       | employees  | idx_first_name | 2021-11-13 15:30:00 | n_diff_pfx01 |       1297 |          20 | first_name                        |
| test_db       | employees  | idx_first_name | 2021-11-13 15:30:00 | n_diff_pfx02 |     299343 |          20 | first_name,emp_no                 |
| test_db       | employees  | idx_first_name | 2021-11-13 15:30:00 | n_leaf_pages |        309 |        NULL | Number of leaf pages in the index |
| test_db       | employees  | idx_first_name | 2021-11-13 15:30:00 | size         |        353 |        NULL | Number of pages in the index      |
| test_db       | employees  | idx_hire_date  | 2021-11-13 15:30:00 | n_diff_pfx01 |       5128 |          20 | hire_date                         |
| test_db       | employees  | idx_hire_date  | 2021-11-13 15:30:00 | n_diff_pfx02 |     300069 |          20 | hire_date,emp_no                  |
| test_db       | employees  | idx_hire_date  | 2021-11-13 15:30:00 | n_leaf_pages |        231 |        NULL | Number of leaf pages in the index |
| test_db       | employees  | idx_hire_date  | 2021-11-13 15:30:00 | size         |        289 |        NULL | Number of pages in the index      |
+---------------+------------+----------------+---------------------+--------------+------------+-------------+-----------------------------------+


-- innodb_table_stats 조회
mysql> select * from mysql.innodb_table_stats
    -> where table_name ='employees'\G
*************************** 1. row ***************************
           database_name: test_db
              table_name: employees
             last_update: 2021-11-13 15:30:00
                  n_rows: 299113
    clustered_index_size: 1057
sum_of_other_index_sizes: 642


인덱스 통계정보에서 stat_name 값은 다음 같은 내용입니다.

stat_name
'n_diff_pfx%' : 인덱스가 가진 유니크한 값의 개수를 의미합니다.
'n_leaf_page' : 인덱스 리프 노드의 페이지 수
size : 인덱스 트리에 전체 페이지수
        

통계정보 자동 갱신과 수집 비율

이번 단계에서는 통계정보 자동 갱신 조건과 수집 비율에 대해서 확인해보도록 하겠습니다.
       

통계정보 자동 갱신

MySQL 에서는 다음과 같은 이벤트가 발생하게 되면 통계정보를 갱신하게 됩니다.

 • 테이블이 새로 오픈되는 경우
 • 테이블의 레코드가 대량으로 변경되는 경우(테이블의 전체 레코드 중에서 1/6 정도의 DML이 실행되는 경우)
 • ANALYZE TABLE 명령어가 실행되는 경우
 • SHOW TABLE STATUS 명령이나 SHOW INDEX FROM 명령이 실행되는 경우
 • InnoDB 모니터가 활성화된 경우
 • innodb_stats_on_metadata 설정이 ON 인상태에서 SHOW TALBE STATUS 명령이 실행되는 경우

이렇게 자주 테이블의 통계정보가 갱신이 되게 되면 애플리케이션의 쿼리가 인덱스 레인지 스캔으로 수행이 되던 플랜에서 어느 날 갑자기 풀 테이블 스캔으로 실행되는, 즉 플랜이 의도치 않게 변경이 될 수도 있습니다.
(물론 플랜이 더 좋은 방향으로도 변경될 수도 있습니다)

또한 innodb_stats_auto_recal 변수의 값을 OFF 로 설정해서 통계 정보가 자동으로 갱신되는 것을 막을 수 있습니다.
innodb_stats_auto_recal 시스템 변수의 기본값은 ON 이므로 영구적인 통계 정보를 이용하고자 할 때는 이 설정을 OFF 로 변경하는 방향도 고려해볼 수 있습니다.

테이블 레벨에서도 "STATS_AUTO_RECALC" 속성의 설정을 통해서 자동으로 통계정보를 수집할지 여부를 결정할 수 있습니다.

• STATS_AUTO_RECALC=1
테이블의 통계정보를 자동 수집하며 테이블의 데이터가 약 10% 가 변경될 때 통계가 다시 수집됩니다.

• STATS_AUTO_RECALC=0
테이블의 통계정보를 자동 수집을 비활성화 합니다

• STATS_AUTO_RECALC=DEFAULT
테이블의 통계정보를 자동 수집 여부를 innodb_stats_auto_recalc 시스템 변수의 값으로 결정합니다.
innodb_stats_auto_recalc 시스템 변수의 기본값은 ON 으로 자동 통계정보 수집 활성화입니다.

            

통계 수집 비율

MySQL 5.5 버전에서는 테이블의 통계 정보를 수집할 때 몇개의 InnoDB 테이블 블록을 샘플링 할지를 결정하는 옵션으로 innodb_stats_sample_pages 시스템 변수가 제공되었으나 MySQL 5.6 에서 부터 이 시스템 변수는 Deprecated 되었습니다.

MySQL 5.6 버전에서는 대신 innodb_stats_transient_sample_pages 와 innodb_stats_persistent_sample_pages 2개의 시스템 변수로 분리되었습니다.

• innodb_stats_transient_sample_pages
이 시스템 변수의 기본값은 8인데, 이는 자동으로 통계 정보 수집이 실행될 때 8개 페이지만 임의로 샘플링해서 분석하고 그 결과를 통계정보를 활용한다는 것을 의미합니다.
해당 시스템 변수는 통계정보를 딕셔너리 테이블에 저장 유무를 설정하는 innodb_stats_persistent 시스템 변수가 비활성화 된 경우에만 적용됩니다.

• innodb_stats_persistent_sample_pages
기본값은 20이며, ANALYZE TABLE 명령이 실행되면 임의로 20개 페이지만 샘플링해서 분석하고 그 결과를 영구적인 통계 정보 테이블에 저장하고 활용함을 의미합니다.
innodb_stats_persistent가 활성화되면 innodb_stats_persistent_sample_pages 이 대신 적용됩니다.

영구적으로 통계정보를 사용한다면 MySQL 서버의 점검이나 사용량이 많지 않은 시간을 이용해 더 정확한 통계 정보를 수집할 수도 있습니다. 
물론 더 정확한 통계 정보 수집에는 많은 시간이 소요되겠지만, 이 통계 정보의 정확성에 의해 쿼리의 성능이 결정되기 때문에 시간을 투자할 충분한 가치가 있다고는 생각 합니다.

이처럼 더 정확한 통계 정보를 수집하고자 한다면 시스템 변수에 높은 값을 설정하면 조금 더 정확한 통계 정보를 수집할 수는 있지만, 통계를 수집할 때 I/O 증가 와 통계 정보 수집 시간이 길어질 수 있으므로 변수 값은 적절한 설정이 필요 합니다.

      

information_schema_stats_expiry

MySQL 8.0 버전에서 information_schema_stats_expiry 시스템 변수가 추가되면서 통계 정보 관련하여 일부 딕셔너리 테이블에서 변경된 점이 있습니다.

먼저 MySQL 5.7 버전에서 테스트를 진행하도록 하겠습니다.

mysql> select count(*) from tb_test;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+

-- information_schema.TABLES 에서 통계정보가 확인 됩니다.
mysql> select table_name,table_rows,avg_row_length
       from information_schema.TABLES
       where table_name='tb_test';
+------------+------------+----------------+
| table_name | table_rows | avg_row_length |
+------------+------------+----------------+
| tb_test    |   9609638  |       233      |
+------------+------------+----------------+


mysql> select table_name,n_rows,clustered_index_size,
       sum_of_other_index_sizes
       from mysql.innodb_table_stats
       where table_name='tb_test';
+------------+---------+----------------------+--------------------------+
| table_name | n_rows  | clustered_index_size | sum_of_other_index_sizes |
+------------+---------+----------------------+--------------------------+
| tb_test    | 9609638 |         137152       |           14102          |
+------------+---------+----------------------+--------------------------+


mysql> select table_name,index_name,stat_name,stat_value
     from mysql.innodb_index_stats
     where table_name='tb_test';
+------------+------------+--------------+------------+
| table_name | index_name | stat_name    | stat_value |
+------------+------------+--------------+------------+
| tb_test    | PRIMARY    | n_diff_pfx01 |    9609638 |
| tb_test    | PRIMARY    | n_leaf_pages |     136987 |
| tb_test    | PRIMARY    | size         |     137152 |
| tb_test    | idx_1      | n_diff_pfx01 |    5787319 |
| tb_test    | idx_1      | n_diff_pfx02 |    9942726 |
| tb_test    | idx_1      | n_leaf_pages |      12247 |
| tb_test    | idx_1      | size         |      14102 |
+------------+------------+--------------+------------+


-- 테이블을 truncate 합니다.
mysql> truncate table tb_test;


-- 다시 information_schema.TABLES 를 조회 하면 truncate 되어서 0 으로 확인 됩니다.
mysql> select table_name,table_rows,avg_row_length
       from information_schema.TABLES
       where table_name='tb_test';
+------------+------------+----------------+
| table_name | table_rows | avg_row_length |
+------------+------------+----------------+
| tb_test    |      0     |        0       |
+------------+------------+----------------+

MySQL 5.7 에서는 information_schema.TABLES 에서 확인되는 통계정보가 truncate 나 변경에 대해서 위와 같이 정상적으로 확인됩니다.

MySQL 8.0 에서는 아래와 같은 테스트 결과를 확인할 수 있습니다.

-- MySQL 8.0
mysql> select count(*) from tb_test;
+----------+
| count(*) |
+----------+
| 3082751  |
+----------+


mysql> select table_name,table_rows,avg_row_length
       from information_schema.TABLES
       where table_name='tb_test';
+------------+------------+----------------+
| TABLE_NAME | TABLE_ROWS | AVG_ROW_LENGTH |
+------------+------------+----------------+
| tb_test    |  2971870   |      215       |
+------------+------------+----------------+


mysql> select table_name,n_rows,clustered_index_size,
       sum_of_other_index_sizes
       from mysql.innodb_table_stats
       where table_name='tb_test';
+------------+---------+----------------------+--------------------------+
| table_name | n_rows  | clustered_index_size | sum_of_other_index_sizes |
+------------+---------+----------------------+--------------------------+
| tb_test    | 2737323 |        39168         |           0              |
+------------+---------+----------------------+--------------------------+


mysql> select table_name,index_name,stat_name,stat_value
     from mysql.innodb_index_stats
     where table_name='tb_test';
+------------+------------+--------------+------------+
| table_name | index_name | stat_name    | stat_value |
+------------+------------+--------------+------------+
| tb_test    | PRIMARY    | n_diff_pfx01 |    2737323 |
| tb_test    | PRIMARY    | n_leaf_pages |      39021 |
| tb_test    | PRIMARY    | size         |      39168 |
+------------+------------+--------------+------------+


-- truncate table 실행
mysql> truncate table tb_test;


-- information_schema.tables 을 다시 조회
-- truncate 를 하였으나 여전히 건수가 확인됨
mysql> select table_name,table_rows,avg_row_length
       from information_schema.tables
       where table_name='tb_test';
+------------+------------+----------------+
| TABLE_NAME | TABLE_ROWS | AVG_ROW_LENGTH |
+------------+------------+----------------+
| tb_test    |    2971870 |            215 |
+------------+------------+----------------+

-- mysql.innodb_table_stats 통계 딕셔너리 테이블은 정상적으로 반영되었습니다.
mysql> select table_name,n_rows,clustered_index_size,
       sum_of_other_index_sizes
       from mysql.innodb_table_stats
       where table_name='tb_test';  
+------------+--------+----------------------+--------------------------+
| table_name | n_rows | clustered_index_size | sum_of_other_index_sizes |
+------------+--------+----------------------+--------------------------+
| tb_test    |   0    |           1          |            0             |
+------------+--------+----------------------+--------------------------+


일부 INFORMATION_SCHEMA 의 테이블에는 테이블 통계를 제공하는 컬럼(열)이 있습니다

STATISTICS.CARDINALITY
TABLES.AUTO_INCREMENT
TABLES.AVG_ROW_LENGTH
TABLES.CHECKSUM
TABLES.CHECK_TIME
TABLES.CREATE_TIME
TABLES.DATA_FREE
TABLES.DATA_LENGTH
TABLES.INDEX_LENGTH
TABLES.MAX_DATA_LENGTH
TABLES.TABLE_ROWS
TABLES.UPDATE_TIME


이러한 열은 동적 테이블 메타데이터를 나타냅니다. 즉, 테이블 내용이 변경됨에 따라 변경되는 정보입니다.

기본적으로, MySQL은 mysql.index_stats 및 mysql.table_stats 딕셔너리의 컬럼이 조회 될때 해당 열에 대해 캐시 된 값을 검색하게 됩니다.
이는 스토리지 엔진에서 직접 통계를 검색하는 것보다 더 효율적이게 됩니다.

캐시된 통계를 사용할 수 없거나 만료된 경우 MySQL은 스토리지 엔진에서 최신 통계를 검색하여 mysql.index_stats 및 mysql.table_stats 사전 테이블 에 캐시합니다 . 후속 쿼리는 캐시된 통계가 만료될 때까지 캐시된 통계를 검색합니다.

information_schema_stats_expiry 캐시 통계가 만료되기 전에 세션 변수는 시간의 기간을 정의합니다.
기본값은 86400초(24시간)이지만 최대 1년까지 기간을 연장할 수 있다.

항상 스토리지 엔진에서 직접 최신 통계를 검색하고 캐시된 값을 무시하려면 information_schema_stats_expiry 시스템변수를 0 으로 설정하면 됩니다.

또한 캐시된 값을 업데이트하려면 ANALYZE TABLE 를 사용하면 됩니다.

그래서 MySQL 8.0 버전에서는 information_schema_stats_expiry 시스템 변수를 기본값으로 사용할 경우 위에서 리스트 된 딕셔너리 테이블 과 컬럼은 이와 같이 캐시된 값이라서 innodb_table_stats 의 통계정보와 차이가 있을 수 있으므로 innodb_table_stats 도 같이 확인이 필요할 것이라고 생각됩니다.

Note

파티션별 통계정보 수집(ANALYZE) 은 아래 명령어로 진행하면 되며 파티션 정보(파티션 이름 정보)는 INFORMATION_SCHEMA.PARTITIONS 에서 확인할 수 있습니다.

mysql> ALTER TABLE 테이블명 ANALYZE PARTITION 파티션명;

      

Reference

Reference Book
 • Real MySQL 8.0

Reference Site
 • mysql.com/innodb-persistent-stats
 • mysql.com/innodb_stats_persistent_sample_pages
 • mysql.com/innodb_stats_transient_sample_pages
 • mysql.com/schema_stats_expiry


이어지는 다음 글



관련된 다른 글

 

 

 

 

 

      

0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x