Open danbi5228 opened 1 year ago
GROUP BY
와 처리 방법이 비슷하여 인덱스 사용 여부가 GROUP BY
의 요건과 거의 흡사
ORDER BY
절에 사용돼야 하는 것은 아님, 왼쪽 부터 일치하면 된다인덱스가 (COL_1 ASC, COL_2 ASC, COL_3 ASC, COL_4 ASC)
와 같이 정의됐을 때
ORDER BY
절에 명시되지 않음... ORDER BY COL_2, COL_3
ORDER BY
절의 칼럼 순서가 일치하지 않음... ORDER BY COL_1, COL_3, COL_2
ORDER BY
절의 다른 칼럼은 오름차순 인데, 두 번째 칼럼인 COL_2의 정렬 순서가 내림차순이라서 사용 할 수 없음
... ORDER BY COL_1, COL_2 DESC, COL_3
ORDER BY
절에는 COL_2 칼럼이 명시되지 않음... ORDER BY COL_1, COL_3
ORDER BY
절에 명시됐음... ORDER BY COL_1, COL_2, COL_3, COL_4, COL_5
참고로 ORDER BY
절에서 ASC나 DESC가 생략되면 기본은 오름차순으로 해석
쿼리에 WHERE
, GROUP BY
, ORDER BY
절만 포함돼 있다면 사용된 절 하나에만 초점을 맞춰서 인덱스를 사용할 수 있게 튜닝하면 되지만 실제 애플리케이션에서 사용하는 쿼리는 그렇게 단순하지 않다
그리고 SQL 문장이 WHERE
절과 ORDER BY
절을 가지고 있을 때 WHERE
조건은 A 인덱스를 사용하고 ORDER BY
는 B 인덱스를 사용하도록 쿼리가 실행될 수는 없다
WHERE
절과 ORDER BY
절이 동시에 같은 인덱스를 이용
WHRER
절의 비교 조건에서 사용하는 칼럼과 ORDER BY
절의 정렬 대상 칼럼이 모두 하나의 인덱스에 연속해서 포함돼 있을 때
다른 두 방법보다 훨씬 빠른 성능을 보이기에 가능한 이 방식으로 처리하도록 튜닝하는 거나 인덱스를 생성하는 것이 좋다
WHERE
절만 인덱스 이용
ORDER BY
절은 인덱스 이용이 불가능하며, 인덱스를 통해 검색된 결과 레코드를 별도의 정렬 처리 과정(Using Filesort)을 거쳐 정렬을 수행한다WHERE
절의 조건에 일치하는 레코드의 건수가 많지 않을 때 효율적인 방식ORDER BY
절만 인덱스를 이용
ORDER BY
절은 인덱스를 이용해 처리하지만, WHERE
절은 인덱스를 이용하지 못함
ORDER BY
절의 순서대로 인덱스를 읽으면서 레코드 한 건씩 WHERE
절의 조건에 일치하는지 비교하고, 일치하지 않을 때는 버리는 형태로 처리함
아주 많은 레코드를 조회해서 정렬해야 할 때는 이런 형태로 튜닝하기도 함
WHERE
절에서 동등 비교 조건으로 비교된 칼럼과 ORDER BY
절에 명시된 칼럼이 순서대로 빠짐없이 인덱스 칼럼의 왼쪽부터 일치해야 한다
WHERE
절에 동등 비교 조건으로 사용된 칼럼과 ORDER BY
절의 칼럼이 중첩되는 부분은 인덱스를 사용할 때 문제 되지 않음
하지만 중간에 빠지는 칼럼이 있으면 둘 다 인덱스를 사용할 수 없다
WHERE
절만 인덱스를 이용할 수 있다인덱스가 (COL_1 ASC, COL_2 ASC, COL_3 ASC, COL_4 ASC)
로 정의됐다고 가정할 때
WHERE
절과 ORDER BY
절이 결합된 두 가지 패턴의 쿼리를 보면
# 1번
...
WHERE COL_1 = ?
ORDER BY COL_2 ASC, COL_3 ASC
# 2번
...
WHERE COL_1 = ?, COL_2 = ?, COL_3 > ?
ORDER BY COL_3 DESC, COL_4 ASC
2번 처럼 ORDER BY
절에 해당 칼럼이 사용되고 있다면 WHERE
절에 동등 비교 이외의 연산자로 비교돼도 WHERE
과 ORDER BY
조건이 모두 인덱스를 이용할 수 있다
일반적으로 WHERE
절에서 동등 비교로 사용된 칼럼과 ORDER BY
절의 칼럼이 인덱스를 구성하는 칼럼과 같은 순서로 연속해서 사용됐는지를 확인해야 한다
SELECT *
FROM tb_Test
WHERE col_1=10
ORDER BY COL_2, COL_3;
ORDER BY
절의 칼럼 순서가 인덱스의 칼럼 순서와 달라서 정렬할 때 인덱스를 이용하지 못할 것 처럼 보이는데
SELECT *
FROM tb_Test
WHERE col_1=10
ORDER BY COL_1, COL_2, COL_3;
WHERE
조건이 상수로 동등 비교를 하고 있기 때문에 ORDER BY
절에 COL_1 칼럼을 추가해도 정렬 순서에 변화가 없다
하지만 이렇게 변경된 쿼리는 WHERE
절과 ORDER BY
절이 동시에 인덱스를 이용할 수 있는지 더 쉽게 판단할 수 있다
GROUP BY
와 ORDER BY
가 인덱스를 사용할 수 있을지 없을지 모호할 때는 이처럼 쿼리를 조금 변경해서 원본 쿼리가 같은 순서나 결과를 보장하는지 확인해 보면 된다
WHERE
조건 절에서 범위 조건의 비교가 사용될 때는?
# 1번
SELECT *
FROM tb_Test
WHERE COL_1 > 10
ORDER BY COL_1, COL_2, COL_3;
# 2번
SELECT *
FROM tb_Test
WHERE COL_1 > 10
ORDER BY COL_2, COL_3;
1번 예제는 col_1 > 10
조건을 만족하는 값이 여러 개 일 수 있지만 ORDER BY
절에 COL_1 부터 3까지 순서대로 모두 명시됐기 때문에 인덱스를 사용해 처리할 수 있다
하지만 2번 예제는 WHERE
절에서 범위 조건으로 검색됐는데, ORDER BY
절에서 COL_1이 명시되지 않았기 때문에 정렬할 때 인덱스를 이용할 수 없게 된다
다음과 같이 WHERE
절과 ORDER BY
절에 명시된 칼럼의 순서가 일치하지 않거나 중간에 빠지는 칼럼이 있으면 인덱스를 이용해 WHERE
절과 ORDER BY
절을 모두 처리하기란 불가능
...WHERE COL_1=10 ORDER BY COL_3, COL_4
...WHERE COL_1>10 ORDER BY COL_2, COL_3
...WHERE COL_1 IN (1,2,3,4) ORDER BY COL_2
WHERE
절과 GROUP BY
절의 조합도 모두 똑같은 기준이 적용된다
WHERE
절과 ORDER BY
나 GROUP BY
절의 조합에서 인덱스의 사용 여부를 판단하는 능력은 상당히 중요함
GROUP BY
절에서 명시된 칼럼과 ORDER BY
절에서 명시된 칼럼의 순서와 내용이 모두 같아야 한다
인덱스를 이용하지 못하는 예시
... GROUP BY col_1, col_2 ORDER_BY col_2
... GROUP BY col_1, col_2 ORDER_BY col_1, col_3
MySQL 5.7 버전 까지는 GROUP BY
가 칼럼에 대한 정렬까지 수행하는 것이 기본 작동 방식
8.0 버전 부터는 칼럼의 정렬까지는 보장하지 않는 형태로 바뀌었기에 그루핑과 정렬을 모두 수행하기 위해서는
GROUP BY
와 ORDER BY
절 모두 명시해야 한다
WHERE 절, ORDER BY 절, GROUP BY 절이 모두 포함된 쿼리가 인덱스를 사용하는지 판단하는 방법
다음과 같은 3개의 질문을 기본으로 65p 그림에 나온 흐름으로 적용해보면 된다
각 절이 인덱스를 사용할 수 있는지에 따른 인덱스 사용 여부 판단
WHERE | GROUP BY | ORDER BY | 결과 |
---|---|---|---|
T | T | T | WHERE 절, GROUP BY 절, ORDER BY 절 모두 인덱스 사용 |
T | T | F | WHERE 절만 인덱스 사용 |
T | F | WHERE 절만 인덱스 사용 | |
F | T | T | GROUP BY 절, ORDER BY 절 인덱스 사용 |
F | T | F | 인덱스 전혀 사용 못함 |
F | F | 인덱스 전혀 사용 못함 |
... WHERE salay*10 > 15000;
(인덱스 사용 불가) -> ... WHERE salay> 15000/10;
(인덱스 사용 가능)
다음 스터디
2022-01-05 pm 10:30
학습 범위
정리 범위