인덱스 적용 #919
Replies: 9 comments 1 reply
-
인덱스 사용 기준 잡기인덱스는 검색 속도를 높이기 위해서 사용한다. 하지만 특정 기준을 잡지 않고 인덱스를 사용하면 오히려 성능이 낮아질 수 있다. 어떤 기준으로 인덱스를 설정할까? 1. Cardinality가 높은 컬럼
2.
|
Beta Was this translation helpful? Give feedback.
-
인덱스를 붙였을 때 발생하는 리소스1. 공간 사용:인덱스는 추가적인 데이터 구조이기 때문에 디스크 공간을 더 차지한다. 2. 인덱스 업데이트 비용
데이터베이스가 특정 데이터를 더 쉽게 찾을 수 있도록 만들어둔 "목차" |
Beta Was this translation helpful? Give feedback.
-
인덱스 적용한 부분1. Review 테이블 - review_group_id 컬럼
2. ReviewGroup 테이블 - review_request_code 컬럼
|
Beta Was this translation helpful? Give feedback.
-
인덱스 미적용 부분Templatetemplate은 현재 데이터 2개, 늘어난다고 해도 크게 늘어나지 않음. 따라서 인덱스를 붙이면 아주 작은 차이로 빠르긴하나 체감할 수 없는 정도임. 하지만 인덱스를 붙였을 때의 인지적 부담을 갖고 가야하는 점이 단점으로 느껴져 인덱스를 적용하지 않음
Sectionsection은 현재 데이터 11개, Template과 같은 이유로 인덱스 미적용 QuestionoptionItem은 현재 데이터 20개, Template과 같은 이유로 인덱스 미적용 OptionGroupoptionGroup은 현재 데이터 9개, Template과 같은 이유로 인덱스 미적용 OptionItemoptionItem은 현재 데이터 63개 List<OptionItem> findAllByOptionType(OptionType optionType);
public enum OptionType {
CATEGORY, KEYWORD,
} CheckBoxAnswer, TextBoxAnswerreviewId가 각 테이블의 외래키라 이미 넌클러스트 인덱스가 붙어져있어서 붙일 필요가 없음. TemplateSectionTemplateSection은 현재 데이터 11개, 늘어난다고 해도 크게 늘어나지 않음. 따라서 테이블 규모가 작으므로 인덱스 미적용. SectionQuestionSectionQuestion은 현재 데이터 20개, 늘어난다고 해도 크게 늘어나지 않음. 따라서 테이블 규모가 작으므로 인덱스 미적용. CheckBoxAnswerSelectedOptioncheckbox_answer_id가 fk라 이미 넌클러스트 인덱스가 붙어져있음 |
Beta Was this translation helpful? Give feedback.
-
인덱스 성능 확인을 위한 대량 데이터 삽입서비스가 성장하는 상황을 구성하기 위해 대량의 더미 데이터를 구성한다. MySQL의 Procedure를 통해 SQL을 반복적으로 실행하여 데이터를 추가했다. -- Procedure 생성
DELIMITER $$
CREATE PROCEDURE insert_dummy_review_group_data()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i <= 100000 DO -- 반복 횟수 설정
INSERT INTO review_group (group_access_code, project_name, review_request_code, reviewee, template_id)
VALUES (
LPAD(FLOOR(RAND() * 10000), 4, '0'), -- group_access_code 4자리
CONCAT('Project_', i),
LPAD(FLOOR(RAND() * 100000000), 8, '0'), -- review_request_code 8자리
CONCAT('Reviewee_', i),
1
);
SET i = i + 1;
END WHILE;
END$$
DELIMITER ;
리뷰 그룹 더미 데이터 생성을 위한 프로시저를 생성하는 쿼리이다. 생성된 프로시저는 아래 쿼리로 확인 가능하다. -- Procedure 확인
SELECT ROUTINE_NAME
FROM information_schema.ROUTINES
WHERE ROUTINE_TYPE = 'PROCEDURE'
AND ROUTINE_SCHEMA = 'review_group'; 생성된 프로시저는 CALL 함수를 통해 실행할 수 있다. -- Procedure 실행
CALL insert_dummy_review_data(); 프로시저가 실행되면 설정된 반복 횟수만큼 SQL을 실행하여 데이터를 반복적으로 추가한다. |
Beta Was this translation helpful? Give feedback.
-
성능 비교를 위한 실행 결과 확인법인덱스 사용 전후 조회 쿼리 성능 비교를 위해 실행하는 쿼리를 분석할 필요가 있다. 실행하는 쿼리에 EXPLAIN SELECT * FROM review_group rg WHERE review_request_code = '02920153';
EXPLAIN ANALYZE SELECT * FROM review_group rg WHERE review_request_code = '02920153';
쿼리 실행 결과-> Filter:
(rg.review_request_code = '02920153')
(cost=31679 rows=29855)
(actual time=0.0979..169 rows=1 loops=1)
-> Table scan on rg
(cost=31679 rows=298554)
(actual time=0.0468..142 rows=300001 loops=1)
먼저 수행된 단계가 들여쓰기 되어 표시된다. 따라서 Table scan 단계 이후 Filter 단계가 수행되었다. Table scan 단계
Filter 단계
|
Beta Was this translation helpful? Give feedback.
-
인덱스 생성하는 법review_group 테이블에 review_request_code 인덱스를 생성했다. CREATE INDEX review_group_idx_review_request_code ON review_group (review_request_code); 테이블에 인덱스가 잘 생성되었는지 다음과 같은 쿼리로 확인할 수 있다. SHOW INDEX FROM review_group; PK를 기준으로 클러스터드 인덱스가 자동 생성된 것을 볼 수 있고, reviewRequestCode를 기준으로 방금 생성한 보조 인덱스도 확인할 수 있다. |
Beta Was this translation helpful? Give feedback.
-
인덱스 설정 유무에 따른 성능 차이 보기1. review_group 테이블에 review_requets_code 컬럼에 인덱스 적용인덱스 사용 전 쿼리 실행 결과-> Filter:
(rg.review_request_code = '02920153')
(cost=31679 rows=29855)
(actual time=0.0979..169 rows=1 loops=1)
-> Table scan on rg
(cost=31679 rows=298554)
(actual time=0.0468..142 rows=300001 loops=1) 인덱스 생성review_group 테이블에 review_request_code 인덱스를 생성했다. CREATE INDEX review_group_idx_review_request_code ON review_group (review_request_code); Cardinality 컬럼을 보면 인덱스 키가 해당 컬럼에 얼마나 존재하는지 확인 할 수 있다. PK와 동일한 것으로 보아 인덱스 효율이 높을 것으로 예상된다. 인덱스 사용 후 쿼리 실행 결과이제 다시 이전의 쿼리를 실행하고 다음과 같은 결과가 나왔다. EXPLAIN ANASELECT * FROM review_group rg WHERE review_request_code = '02920153' -> Index lookup on rg using review_group_idx_review_request_code
(review_request_code='02920153')
(cost=1.1 rows=1)
(actual time=0.0358..0.0376 rows=1 loops=1)
1.1의 비용으로 1개의 결과가 나올 것으로 예상했다. 결과는 0.0358밀리초(0.038초)의 비용으로 1개의 row를 찾았다. 앞선 결과에서 300,001 개의 행을 스캔하고 1개의 결과를 찾는 데 169밀리초 (0.169초)가 소요되었으나, 인덱스 사용 시 1개의 row 만을 스캔하고 찾는 데 0.0358밀리초(0.0000358초)로 약 4720.67배 더 빨랐다! |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
인덱스가 왜 필요한가?
Beta Was this translation helpful? Give feedback.
All reactions