2013-01-30 7 views
4

A, B 및 C와 같이 3 innodb 테이블이 있습니다.이 세 테이블을 조인하여 결과를 생성하는 쿼리가 있습니다. , 그러나MySQL : ANALYZE TABLE에 대한 임의의 결과

- C -

B :

내가 사용 명령을 'EXPLAIN'쿼리를 테스트했다 태초에
SELECT A.a, B.b, C.c 
from A 
join B on A.id = B.a_id 
join C on C.id = B.c_id 
where A.a = 'example' and B.b < 10; 

, 그것은 나에게 다음과 같은 순서를 제공합니다 이것은 최적이 아닙니다. 그래서 모든 테이블에 '표를 분석'실행하고 그것은 나를 제공 :

A - B를 - 나는 그것이 올바른 순서하다고 생각하는 C

.

그런 다음 SQL을 프로덕션에 배치 했으므로 아무 이유없이 1 달 후에 실행 계획이 B-C-A 인 잘못된 옵션으로 다시 전환되었습니다. 그 후, 나는 을 다시 실행하려고 시도했는데,에 대해 번을 다시 시도했지만, 이번에는 결과가 혼란 스럽다. 때로는 저에게 B - C - A를 줄 때가 있습니다. 때로는 A - B - C와 때로는 다른 실행 계획을 제공합니다.

그래서 제 질문은 :

  1. 왜 배포 후 실행 계획 변경?
  2. (데이터가 업데이트되고 빠르게 변경되므로 향후 최적의 계획이 변경 될 수 있음) 이외에도 최적의 계획이 항상 보장된다는 보장이 있습니까?

답변

6

옵티마이 저는 테이블을 재정렬하고 값의 테이블, 기수의 크기, 분포에 대해 메모리 통계를 기반으로 인덱스를 사용하는 방법에 대한 선택을하게, 인덱스는이 통계는 이 아닌 절대적으로 정확한 전혀 추정하고있다 등 타임스.

InnoDB는 ANALZYE TABLE을 실행할 때 발생할 수있는 상황을 수시로 업데이트합니다.

그러나 여전히 메모리의 통계가 옵티 마이저를 다른 선택으로 만드는 첨단에있는 경우가 있으므로이 플립 플롭 동작을 볼 수 있습니다.

쿼리에 index hints을 지정하여 인덱스를 선택하기위한 최적화 프로그램의 기본 알고리즘을 재정의 할 수 있습니다.

STRAIGHT_JOIN을 지정하여 순서 변경 테이블의 최적화 알고리즘의 기본 알고리즘을 무시할 수 있습니다. 즉, FROM 절에서 지정한 순서대로 테이블을 읽고 순서를 바꾸지 마십시오.

쿼리 수정 자 (예 : DISTINCT)로 STRAIGHT_JOIN을 사용할 수 있습니다. SELECT 직후에 넣기 :

SELECT STRAIGHT_JOIN A.a, B.b, C.c 
from A 
join B on A.id = B.a_id 
join C on C.id = B.c_id 
where A.a = 'example' and B.b < 10; 

그러나 인덱스 힌트를 사용하거나 힌트를 너무주의 깊게 조심하십시오. 옵티마이 저가 데이터의 크기와 분포가 약간 변경된 다음 주 플립 플롭 동작을 피할 수 있습니다.코드에서 오버라이드가 너무 많으면 옵티마이 저가 더 나은 작업을 수행 할 수 없습니다.

+0

구체적인 설명에 감사드립니다. innoDB가 수시로 통계를 갱신하고, 데이터베이스 테이블이 높은 빈도 (50 초)로 업데이트/삽입되었다는 것을 고려하면, 일단 그것이 '첨단'으로 떨어지면 쉽게 되돌아 오지 않는다는 것을 알았다. . "ANALYZE TABLE"을 명시 적으로 실행해야합니다. 어떻게 그럴 수 있습니까? –

+0

통계는 ANALYZE TABLE 또는 SHOW TABLE STATUS 또는 INFORMATION_SCHEMA.TABLES에 대한 질의 후 업데이트됩니다. 따라서 매 1 시간마다 또는 10 분마다 또는 원하는 모든 일정에 대해 이러한 진술 중 하나를 사용할 수 있습니다. 통계 업데이트의 영향은 매우 적지 만 * 모든 * 업데이트 후에는 그렇게하지 않을 정도로 충분히 큽니다. –