Sasha Pachev의 MySQL 내부 이해하기 172 페이지 9 장 (파서 및 최적화 프로그램)에 따르면
다음은 다음과 같은 쿼리 평가 분석입니다.
- 테이블에서 레코드를 검색하는 데 사용할 수있는 키를 결정하고 각 테이블에 가장 적합한 키를 선택하십시오.
- 각 테이블에 대해 키를 읽는 것보다 테이블 스캔이 더 나은지 여부를 결정하십시오. 키 값과 일치하는 레코드가 많으면 키의 장점이 줄어들고 테이블 스캔이 더 빨라집니다.
- 쿼리에 둘 이상의 테이블이있을 때 테이블이 조인되는 순서를 결정하십시오.
- WHERE 절을 다시 작성하여 데드 코드를 제거하고 불필요한 계산을 줄이고 가능한 경우 키를 사용하는 방법을 열 수 있도록 제약 조건을 변경하십시오.
- 조인에서 사용하지 않는 테이블을 제거하십시오.
ORDER BY
및에 키를 사용할 수 있는지 확인하십시오 GROUP BY
.
- 서브 쿼리를 단순화하고 결과를 캐시 할 수있는 정도를 결정하십시오.
- 뷰 병합 (뷰 참조를 매크로로 확장)
같은 페이지에 다음과 같이 표시됩니다.
MySQL 최적화 용어에서 모든 쿼리는 조인 집합입니다. 여기서 join 이라는 용어 는 SQL 명령보다 더 광범위하게 사용됩니다. 하나의 테이블에 대한 쿼리는 퇴화 조인입니다. 일반적으로 하나의 테이블에서 레코드를 조인으로 읽는 것을 생각하지 않지만 기존의 조인에 사용 된 동일한 구조와 알고리즘은 하나의 테이블만으로 쿼리를 해결하기 위해 완벽하게 작동합니다.
발문
존재하는 키, 데이터 양 및 쿼리의 표현으로 인해 MySQL Joins는 때때로 우리 자신의 이익을 위해 일하거나 (또는 우리를 다시 방문하기 위해) 예상하지 않았고 신속하게 설명 할 수없는 결과를 얻을 수 있습니다.
나는 전에이 기발함에 대해 썼다.
MySQL Query Optimizer는 쿼리 평가 중에 특정 키를 닫을 수 있기 때문입니다.
@Phil의 의견은이 답변을 게시하는 방법을 알려줍니다 (@Phil의 의견에 +1)
@ypercube의 의견 (이것도 +1)은 MySQL의 Query Optimizer가 원시이기 때문에 내 게시물의 컴팩트 버전입니다. 불행히도 외부 스토리지 엔진을 다루기 때문입니다.
결론
실제 질문과 관련하여 MySQL Query Optimizer는 각 쿼리의 수행 메트릭을 결정합니다.
- 행을 계산
- 키 선택
- 간헐적 결과 세트 마사지
- 예, 실제 가입
쿼리를 다시 작성 (리팩토링)하여 실행 순서를 강제해야 할 수 있습니다.
여기 당신이 준 첫 번째 쿼리가 있습니다
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
WHERE를 먼저 평가하려면 다시 작성하십시오.
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
그것은 분명히 EXPLAIN 계획을 바꿀 것입니다. 더 나은 결과를 얻을 수 있습니다.
한 번이 기술을 적용한 StackOverflow의 질문에 대답했습니다. EXPLAIN은 끔찍했지만 성능은 다이나마이트였습니다. 올바른 인덱스가 있고 하위 쿼리에서 LIMIT를 사용했기 때문에 작동했습니다 .
주가와 마찬가지로 쿼리와 관련하여이를 표현하려고 할 때 제한이 적용되고 결과가 다를 수 있으며 과거 성과가 미래 결과를 나타내는 것은 아닙니다.