MySQL Query Optimizer는 어디에서 인덱스 통계를 읽습니까?


14

MySQL 최적화 프로그램이 쿼리 비용 (준비)을 추정 할 때 테이블에 사용할 수있는 인덱스 목록을 얻는 위치를 결정하려고합니다.


개발자와 DBA가 인덱스 통계를 컴파일하고 저장하는 방법에 대해 일시 정지하고 생각해야하므로이 좋은 질문에 +1하십시오.
RolandoMySQLDBA

참고로, mysql 문서 웹 사이트에서 : < dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html >> 각각에 8 개의 무작위 다이빙을 수행 ANALYZE TABLE하여 (카디널리티 열의 카디널리티 열에 표시됨) 인덱스 카디널리티를 결정 SHOW INDEX합니다. 인덱스 트리 및 인덱스 카디널리티 추정값의 업데이트. 이는 추정치 일 뿐이므로 ANALYZE TABLE을 반복 실행하면 다른 숫자가 생성 될 수 있습니다. 이것은 ANALYZE TABLE모든 행을 고려하지 않기 때문에 InnoDB 테이블 에서는 빠르지 만 100 % 정확하지는 않습니다.
Chen Xie

답변:


6

이에 대한 직접적인 대답은

information_schema.statistics

mysql> desc information_schema.statistics;
+---------------+---------------+------+-----+---------+-------+
| Field         | Type          | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(512)  | NO   |     |         |       |
| TABLE_SCHEMA  | varchar(64)   | NO   |     |         |       |
| TABLE_NAME    | varchar(64)   | NO   |     |         |       |
| NON_UNIQUE    | bigint(1)     | NO   |     | 0       |       |
| INDEX_SCHEMA  | varchar(64)   | NO   |     |         |       |
| INDEX_NAME    | varchar(64)   | NO   |     |         |       |
| SEQ_IN_INDEX  | bigint(2)     | NO   |     | 0       |       |
| COLUMN_NAME   | varchar(64)   | NO   |     |         |       |
| COLLATION     | varchar(1)    | YES  |     | NULL    |       |
| CARDINALITY   | bigint(21)    | YES  |     | NULL    |       |
| SUB_PART      | bigint(3)     | YES  |     | NULL    |       |
| PACKED        | varchar(10)   | YES  |     | NULL    |       |
| NULLABLE      | varchar(3)    | NO   |     |         |       |
| INDEX_TYPE    | varchar(16)   | NO   |     |         |       |
| COMMENT       | varchar(16)   | YES  |     | NULL    |       |
| INDEX_COMMENT | varchar(1024) | NO   |     |         |       |
+---------------+---------------+------+-----+---------+-------+
16 rows in set (0.01 sec)

당신은 그 테이블에서 선택할 수 있습니다

SELECT * FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='mytable';

또는 수행하여 통계를 참조하십시오

mydb.mytable에서 색인 표시;

이 테이블은 쓰기가 많은 환경에서 항상 정확한 것은 아닙니다. 정기적으로 자주 업데이트되는 모든 MyISAM 테이블에 대해 ANALYZE TABLE 을 실행해야합니다 . 그렇지 않으면 information_schema.statistics에 의존하는 MySQL Query Optimizer가 쿼리에 대한 EXPLAIN 계획을 개발할 때 때때로 잘못된 선택을 할 수 있습니다. 인덱스 통계는 가능한 최신 상태 여야합니다.

ANALYZE TABLE에는 InnoDB 테이블에 대한 영향이 전혀 없습니다. InnoDB에 대한 모든 인덱스 통계는 BTREE 페이지로 다이빙하여 요청시 계산됩니다. 따라서 InnoDB 테이블에 대해 SHOW INDEXES FROM을 실행할 때 표시되는 카디널리티는 항상 근사치입니다.

업데이트 2011-06-21 12:17 EDT

ANALYZE TABLE의 설명을 위해, 다시 말하겠습니다. InnoDB 테이블에서 ANALYZE TABLE을 실행하는 것은 완전히 쓸모가 없습니다. InnoDB 테이블에서 ANALYZE TABLE을 실행 한 경우에도 InnoDB 스토리지 엔진은 카디널리티 근사치에 대한 인덱스를 여러 번 반복해서 인덱스에 표시합니다. 나누 방금 컴파일 한 통계를 버립니다 . 실제로 Percona는 ANALYZE TABLE에서 몇 가지 테스트를 수행했으며 그 결론에 도달했습니다.


5

Re : ANALYZE TABLE에는 InnoDB 테이블에 대한 영향이 전혀 없습니다.

이 진술이 사실인지 확실하지 않습니다. 우리는 innodb 테이블을 많이 읽고 쓰고 있으며 mysql 옵티마이 저가 잘못된 선택을 할 때 쿼리의 Explain 출력은 나쁜 전략을 보여줍니다. 또한 Innodb 테이블에서 INDEXES 표시는 카디널리티 값에 많은 차이가 있음을 보여줍니다. 그러나 해당 innodb 테이블에서 ANALYZE 명령을 실행하면 Explain 계획을 수정하고 카디널리티의 분산 동작을 제거합니다. Innodb 테이블의 ANALYZE table 명령이 항상 도움이되는지 아닌지는 모르겠지만 우리의 경우 시간의 약 99 %가 도움이되었습니다.

쿼리에 "STRAIGHT_JOIN"을 포함 시켜서 mysql 옵티마이 저의 잘못된 선택을 완전히 제거했습니다. 이것은 mysql 옵티마이 저가 잘못된 선택이나 선택을하지 않고 쿼리에서 정의한 JOIN 조건을 그대로 따릅니다.


InnoDB 테이블에서 ANALYZE TABLE의 쓸모가 없음을 강조하기 위해 답변을 업데이트했습니다.
RolandoMySQLDBA

카디널리티의 차이를 언급했을 때 귀하의 답변에 동의합니다. 그것이 바로 카디널리티 근사치를 말했을 때의 말입니다.
RolandoMySQLDBA

또한 쿼리에서 힌트를 사용하는 것이 MySQL Query Optimizer가 때때로 힌트를 제거하는 경향이있을 때 항상 최선의 방법은 아니라는 언급이 필요했습니다. 다음은 실제로 쿼리 계획의 일부에서 데이터가 사라질 수있는 쿼리에 대한 내부 링크입니다. dba.stackexchange.com/questions/1371/…
RolandoMySQLDBA

2

MyISAM에 대한 ANALYZE TABLE은 전체 테이블을 스캔하고 .MYI 파일에 저장된 통계를 다시 작성합니다. 거의 필요하지 않습니다.

InnoDB에 대한 ANALYZE TABLE 무언가를 - 그것은 언급 다이빙을한다. 문제는 그것이 카디널리티를 제외하고 도움이 될 수도 있고, 상황을 악화시킬 수도 있고, (또는 대부분) 눈에 띄는 차이를 만들지 않을 것입니다.

최신 버전에서는 무작위가 아닌 8 개의 프로브를 (1)보다 무작위로 변경하고 (2) "8"(이것의 장단점이 있습니다!)을 변경하고 (3) 재시작을 통해 저장하는 것을 허용합니다.

결론 : InnoDB는 여전히 '올바른'을 얻지 못했습니다. 느낌이들 때 분석하지만 숨을 참지 마십시오.

최신 정보

재 문구에 ... ANALYZE TABLE일시적으로 InnoDB 테이블의 최적화에 영향 (아마도 도움이 가능하지 않음).

"최신 버전": 5.6.6 (2012) 및 MariaDB 10.1 (2014)부터 통계가 훨씬 잘 처리되었으며 ANALYZE이제는 (1) 덜 자주 필요하며 (2) 더 영구적입니다.

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