안녕하세요.오늘의 내용은 LIMIT 입니다.
select *
from employees ignore index(employees_ix02)
where hire_date between '1986-05-02' and '1986-10-31' -- 건수 1092
order by hire_date desc
limit 10 ;
limit 조건은 오라클의 rownum 과 비슷하긴 하지만 작동하는 방식이 다르기 때문에 주의가 필요합니다.
위 쿼리의 순서입니다.
1.employees 테이블에서 where 조건에 만족하는 레코드를 전부 읽습니다
2.읽어온 레코드를 hire_date 내림차순으로 정렬합니다
3.정렬된 결과에서 상위 10건을 채우면 바로 반환합니다.
Limit 은 where 조건이 아니므로 항상 마지막에 수행합니다.
또한 쿼리에서 모든 레코드의 정렬이 완료되지 않았다 하더라도 limit 에서 필요한 레코드가 준비되면
바로 쿼리를 종료시킵니다.
즉, 상위 10개를 채우면 더 이상 정렬하지 않고 사용자에게 결과를 보냄
limt을 사용하는 쿼리의 케이스별로 어떻게 동작하는지 살펴보겠습니다.
아래는 쿼리 수행 전 후 Sort 누적 현황을 보여줍니다.
-- 1 수행전 sort 누적현황
show session status like 'Sort%' ;
-- Sort_merge_passes 0
-- Sort_range 0
-- Sort_rows 734
-- Sort_scan 76
-- 1 수행후 sort 누적현황 (full table scan 사용)
select *
from employees ignore index(employees_ix02)
where hire_date between '1986-05-02' and '1986-10-31' -- 건수 1092
order by hire_date desc
limit 10;
show session status like 'Sort%' ;
-- Sort_merge_passes 0
-- Sort_range 0
-- Sort_rows 744 --> (+10) 정렬횟수증가되었으나 limit 조건으로 인해 정렬횟수는 10 으로 제한
-- Sort_scan 77 --> (+1) 테이블풀스캔을 사용한 결과로 정렬수행한 횟수 1 증가
인덱스가 없어 풀테이블스캔으로 결과를 가져오지만 1092건 전체를 정렬하지 않고도 멈춤
그래서 limit 을 하면 쿼리의 작업량을 상당히 줄여주는 역할은 가능합니다.
하지만 정렬은 피할 수가 없습니다.
-- 2 수행전 sort 누적현황
show session status like 'Sort%' ;
-- Sort_merge_passes 0
-- Sort_range 0
-- Sort_rows 744
-- Sort_scan 77
create index employees_ix02 on employees(hire_date);
select *
from employees use index(employees_ix02) -- > 인덱스사용
where hire_date between '1986-05-02' and '1986-10-31' -- 건수 1092
order by hire_date desc
limit 10;
-- 2 수행후 sort 누적현황 (employees_ix02 사용)
show session status like 'Sort%' ;
-- Sort_merge_passes 0
-- Sort_range 0
-- Sort_rows 744
-- Sort_scan 77
--> 정렬횟수 증가 없음
-- employees_ix02 인덱스를 이용해 스트리밍방식으로 처리되면 정렬횟수가 증가하지 않음 (즉, 결과가 이미 정렬되어 있어 정렬과정자체가 불필요함)
-- 3 order by 에 인덱스에 포함되지 않는 last_nmae 추가
select *
from employees use index(employees_ix02)
where hire_date between '1986-05-02' and '1986-10-31' -- 건수 1092
order by hire_date desc, last_name
limit 10;
-- 3 수행후 sort 누적현황 (employees_ix02 사용)
show session status like 'Sort%' ;
-- Sort_merge_passes 0
-- Sort_range 1
-- Sort_rows 754 -- > (+10)
-- Sort_scan 77
'MySQL-MariaDB' 카테고리의 다른 글
Hash Join (0) | 2020.08.29 |
---|---|
MaraDB 지식베이스 - table_open_cache 최적화 (0) | 2020.08.23 |
MySQL 진단시 고려할 부분 (0) | 2020.08.22 |
MySQL 테스트 데이터복제 (0) | 2020.08.17 |
innoDB Buffer Usage가 100%를 유지하는 현상 (0) | 2020.06.26 |