SELECT
INSERT, UPDATE의 경우 레코드 단위로 작업을 하기 때문에 성능상 문제가 되는 경우가 별로 없지만, SELECT의 경우 여러 테이블로부터 데이터를 불러와 조합해서 처리하기 때문에 테이블을 어떻게 읽을 것인가에 많은 주의가 필요하다.
인덱스를 사용하기 위한 기본 규칙
인덱스는 B-Tree에 아무런 변환 없이 정렬된 상태로 저장되기 때문에 인덱스를 사용하려면 기본적으로 인덱스 된 칼럼의 값을 그대로 사용해야 한다. 만약 MD5() 함수와 같이 해시 값을 만들어 비교하는 경우 미리 계산된 값을 저장하도록 가상 칼럼(Virtual Column)을 추가하고 그 칼럼에 인덱스를 생성하거나 함수 기반의 인덱스를 사용해야 한다.
값을 변환하지 않는다는 규칙은 WHERE절에서 비교하는 두 값의 데이터 타입이 일치해야 한다는 말과 이어진다. MySQL에서 서로 다른 타입의 비교를 하는 경우 두 데이터를 일치시키게 변환하기 때문에 이 경우도 인덱스를 사용할 수 없게 된다.
WHERE 절의 인덱스 사용
WHERE 조건이 인덱스를 사용하는 방법은 크게 범위 결정 조건과 체크 조건, 두 가지 방식으로 구분된다. 그중에 범위 결정 조건은, 조건절에서 동등 비교 조건이나 IN으로 구성된 조건에 사용된 칼럼들이 인덱스의 칼럼 구성과 좌측에서부터 비교했을 때 얼마나 일치하는가에 따라 달라진다.
WHERE 절에서 AND 연산의 경우 읽어와야 할 레코드의 건수를 줄이는 역할을 하지만 OR을 경우 비교해야 할 레코드가 더 늘어나기 때문에 주의가 필요하다.
GROUP BY 절의 인덱스 사용
GROUP BY 절의 각 칼럼은 비교 연산자를 가지지 않으므로 작업 범위 결정 조건, 체크 조건를 구분해서 생각할 필요 없이, 명시된 칼럼의 순서가 인덱스를 구성하는 칼럼의 순서와 같으면 일단 인덱스를 사용할 수 있다.
WHERE 절과 비슷하게 인덱스 칼럼의 순서와 위치, 좌측 기준 칼럼 등은 비슷하지만 GROUP BY 절에 명시된 칼럼이 하나라도 인덱스에 없으면 GROUP BY 절은 전혀 인덱스를 이용하지 못한다. WHERE 절에서 상수값으로 이미 동등 비교를 한 (좌측에서 순서대로)인덱스 칼럼이라면 GROUP BY 절에서 생략해도 인덱스가 사용 가능하다.
ORDER BY 절의 인덱스 사용
GROUP BY 절과 처리 방법이 상당히 비슷하지만 추가적으로 정렬되는 각 칼럼의 오름차순 및 내림차순 옵션이 인덱스와 같거나 정반대인 경우에만 사용할 수 있다.
WHERE 조건과 ORDER BY(또는 GROUP BY) 절의 인덱스 사용
우리가 사용하는 쿼리 대부분은 WHERE 절과 ORDER BY(또는 GROUP BY)를 섞어 사용하게 된다. 하지만 두 절(SELECT + ORDER BY 또는 ORDERBY + GROUP BY 등등)에서 서로 다른 인덱스를 가지고 쿼리가 실행될 수는 없다.
때문에 (1) WHERE 절과 ORDER BY 절이 동시에 같은 인덱스를 사용하거나, (2) WHERE 절만 인덱스를 사용, (3) ORDER BY 절만 인덱스를 사용하는 경우에 인덱스를 사용할 수 있다. 또 앞서 설명했듯이 WHERE 절에서 좌측에서 순서대로 빠짐없이 상수값과 인덱스를 비교한 경우 ORDER BY(또는 GROUP BY)에서 나머지 인덱스들을 규칙에 맞게 사용한다면 인덱스를 사용할 수 있다.
GROUP BY 절과 ORDER BY 절의 인덱스 사용
GROUP BY절과 ORDER BY 절이 동시에 사용된 쿼리에서 두 절이 모두 하나의 인덱스를 사용해서 처리되려면 두 절에 명시된 칼럼의 순서와 내용이 모두 같아야 한다.
WHERE 조건과 ORDER BY 절, GROUP BY 절의 인덱스 사용
이 경우는 앞서 정리한 내용을 합친 것으로 WHERE 절이 인덱스를 사용할 수 있는 경우와 GROUP BY, ORDER BY 두 절이 인덱스를 사용할 수 있나로 나뉜다. WHERE 절과 별개로 GROUP BY와 ORDER BY는 두 절 중 하나라도 인덱스를 사용하지 못하면 둘 다 사용을 못하고 그 반대의 경우만 사용이 가능하다.
WHERE 절의 비교 조건 사용 시 주의사항
NULL 비교 | MySQL에서는 NULL 값이 포함된 레코드도 인덱스로 관린된다. 따라서 인덱스 칼럼에 대해서 NULL 조건도 인덱스를 사용할 수 있다. |
문자열이나 숫자 비교 | 문자열이나 숫자 칼럼을 비교할 때는 반드시 그 타입에 맞는 상숫값을 사용할 것을 권장한다. |
날짜 비교 | 이 부분은 많은 사람들이 실수하는 부분으로 값 변환에 대한 인덱스 사용 유무를 기억할 필요가 있다. 따라서 상수값을 날짜형으로 변환하여 사용하도록 쿼리를 작성해야 한다. |
단축 평가(Short-Circuit Evaluation)
단축 평가는 AND 연산에서 좌측 논리가 거짓일 경우 우측 논리에 대한 연산을 하지 않는 최적화를 의미한다. 이는 WHERE 절에서도 동일하게 적용받기 때문에 좌측부터 순서대로 조건을 판단하는 특징을 이용해 복잡한 연산이 필요한 조건의 경우 우측으로 배치하도록 하여 최대한 적은 연산을 하도록 유도해야 성능적 이점을 가질 수 있다.
'독서 > 데이터베이스' 카테고리의 다른 글
SQL 메모 정리 [작성중] (0) | 2022.01.05 |
---|---|
트랜잭션과 잠금 (0) | 2022.01.01 |
실행 계획 분석 (0) | 2021.12.29 |
프로그래머스 SQL JOIN (0) | 2021.12.29 |
프로그래머스 SQL IS NULL (0) | 2021.12.29 |