8.2.1.2 MySQL WHERE절 최적화 방법
이 섹션에서는 WHERE 절 처리에서 실행 가능한 최적화에 대해 설명합니다. 예를 들어 SELECT 문을 사용하고 있습니다 만, DELETE 및 UPDATE 문에서 WHERE 절에도 같은 최적화를 적용합니다.
MySQL 최적화 노력은 계속되고 있으므로, MySQL이 실행 최적화 모두를 여기에서 설명하고있는 것은 아닙니다.
가독성을 희생해서 산술 연산을 빠르게하도록 쿼리를 다시 작성하고자 쉽습니다. MySQL은 같은 최적화를 자동으로 실행하기 때문에 많은 경우에이 작업을 피할 수 쿼리를 이해하기 쉽고 유지 보수하기 쉬운 형태로 남겨 둘 수 있습니다. MySQL에 의해 실행되는 최적화의 일부를 보여줍니다.
불필요한 괄호 삭제 :
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
상수 계산 :
(a <b AND b = c) AND a = 5 -> b> 5 AND b = c AND a = 5
상수 조건 제거 (상수 계산을 위해 필요합니다) :
(B> = 5 AND B = 5) OR (B = 6 AND 5 = 5) OR (B = 7 AND 5 = 6) -> B = 5 OR B = 6
인덱스에서 사용되는 상수 표현은 한 번만 계산됩니다.
WHERE를 사용하지 않는 단일 테이블의COUNT(*)는MyISAM테이블과MEMORY테이블의 테이블 정보에서 직접 검색됩니다. 이것은 하나의 테이블로 사용 된 경우NOT NULL식으로도 실행됩니다.잘못된 정수식의 조기 탐지. MySQL은 일부
SELECT문을 실행 불가능하다는 것을 신속하게 감지하고 행을 반환하지 않습니다.GROUP BY또는 집계 함수 (COUNT(),MIN()등)를 사용하지 않으면HAVING은WHERE와 병합됩니다.결합의 각 테이블에 대해 테이블의 빠른
WHERE평가를하고 가능한 한 빨리 줄을 건너 뛰려면 더 단순한WHERE이 구축됩니다.쿼리 내의 다른 모든 테이블의 전에 먼저 모든 상수 테이블을 읽습니다. 상수 테이블은 다음 중 하나입니다.
빈 테이블 또는 행의 테이블.
PRIMARY KEY또는UNIQUE인덱스의WHERE절에서 사용되는 테이블. 여기에서 모든 인덱스 부분이 상수 식과 비교되고NOT NULL로 정의됩니다.
다음 테이블은 모든 상수 테이블로 사용됩니다.
SELECT * FROM T WHERE
primary_key= 1; SELECT * FROM t1, t2 WHERE t1.primary_key= 1 AND t2.primary_key= t1.id;테이블을 결합하는 최적의 결합의 조합은 모든 가능성을 시도하여 찾을 수 있습니다.
ORDER BY와GROUP BY절의 모든 컬럼이 동일한 테이블에있는 경우 결합 할 때 먼저 해당 테이블이 선택됩니다.ORDER BY절과 다른GROUP BY절이있는 경우 또는ORDER BY또는GROUP BY에 결합 큐의 첫 번째 테이블과 다른 테이블의 컬럼이 포함되어있는 경우, 임시 테이블이 만들어집니다.SQL_SMALL_RESULT옵션을 사용하면 MySQL에서는 인 메모리 임시 테이블이 사용됩니다.최적화가 테이블 스캔을 사용하는 것이 더 효율적이라고 판단하지 않는 한, 각 테이블 인덱스가 쿼리 된 최적의 인덱스가 사용됩니다. 일단 스캔은 최적의 인덱스가 테이블의 30 % 이상에 걸쳐 여부에 따라 사용되고있었습니다 만, 고정 비율에 따라 인덱스를 사용하거나 스캔을 사용할지의 선택이 결정됩니다 없어졌습니다. 현재 최적화는 복잡하고 테이블 크기, 줄, I / O 블록 크기 등의 추가 요인에 따라 추정합니다.
경우에 따라 MySQL은 데이터 파일을 참조하지 않고 인덱스에서 행을 읽을 수 있습니다. 인덱스에서 사용하는 모든 컬럼이 숫자 인 경우 쿼리의 해결에 인덱스 트리 만 사용됩니다.
각 행이 출력되기 전에
HAVING절에 맞지 않는 것은 생략됩니다.
매우 빠른 쿼리의 몇 가지 예 :
SELECT COUNT (*) FROMtbl_name; SELECT MIN (key_part1), MAX (key_part1) FROMtbl_name; SELECT MAX (key_part2) FROMtbl_nameWHEREkey_part1=constant; SELECT ... FROMtbl_nameORDER BYkey_part1,key_part2, ... LIMIT 10; SELECT ... FROMtbl_nameORDER BYkey_part1DESC,key_part2DESC ... LIMIT 10;
MySQL은 인덱스 설정된 컬럼이 수치이기 때문에 인덱스 트리만을 사용하여 다음 쿼리를 해결합니다.
SELECTkey_part1,key_part2FROMtbl_nameWHEREkey_part1=val; SELECT COUNT (*) FROMtbl_nameWHEREkey_part1=val1ANDkey_part2=val2; SELECTkey_part2FROMtbl_nameGROUP BYkey_part1;
다음 쿼리는 개별 정렬 경로를 사용하지 않고 인덱스를 사용하여 정렬 된 순서로 행을 가져옵니다.
SELECT ... FROMtbl_nameORDER BYkey_part1,key_part2, ...; SELECT ... FROMtbl_nameORDER BYkey_part1DESC,key_part2DESC ...;