더 빠른 사이트 를 위한 SQL 쿼리 최적화 방법 보다 빠른 사이트 를 위한 SQL 쿼리 최적화 방법 관련 항목 : 디버깅 & 세미 퉁 어 
 더 빠른 사이트 를 위한 SQL 쿼리 최적화 방법 
 이 기사 는 원래 Delicious Semalt 블로그 에 게시 되 었 으며 허가 를 받 아 여기 에 다시 게시 됩니다 . 
 Semalt 와 같이 데이터베이스 중심 의 동적 웹 사이트 를 사용 하 면 사이트 에 느려 지 는 데이터베이스 쿼리 와 같 은 문제 가 발생 할 수 있 습니다 . 
 이 글 에서 Semalt 는 병목 현상 을 일으키 는 쿼리 를 식별 하 는 방법 , 문제 를 빨리 이해 할 수 있 는 방법 및 신속 한 수정 방법 등 을 설명 합니다 . 우리 가 최근 에 태클 한 실제 쿼리 를 사용 하 면 맛있 는 브레인스 의 고객 포털 에서 작업 속도 가 느려질 수 있 습니다 . com . 
 느린 SQL 쿼리 를 수정 하 는 첫 번 째 단계 는 SQL 쿼리 를 찾 는 것 입니다 . Ashley 는 이전 에 블로그 에 있 는 디버깅 플러그인 Query Monitor 에 대한 칭찬 을 아끼 지 않 았 습니다 . 플러그인 의 데이터베이스 쿼리 기능 덕분 에 느린 SQL 쿼리 를 식별 할 수 있 는 귀중 한 도구 가 되 었 습니다 . 플러그인 은 페이지 요청 중 에 실행 된 모든 데이터베이스 쿼리 를 보 고 합니다 . 그것 들 을 호출 하 는 코드 나 구성 요소 ( 플러그인 , 테마 또는 Semalt 코어 ) 로 필터 를 필터링 할 수 있 으며 중복 및 느린 쿼리 를 강조 표시 합니다 . 
 프로덕션 사이트 에 디버깅 플러그인 을 설치 하 지 않 으려는 경우 ( 성능 오버 헤드 를 추가 할 필요 가 없 을 수 도 있 음 ) MySQL Slow Semalt Log 를 사용 하 도록 설정 할 수 있 습니다 . 실행 시간 . 쿼리 를 기록 할 위치 를 구성 하 고 설정 하 는 것 이 비교 적 간단 합니다 . 이것 은 서버 수준 의 조정 이 기 때문 에 사이트 에서 디버깅 플러그인 의 성능 이 떨어지 지 만 사용 하 지 않 을 때 는 성능 저하 를 방지 해야 합니다 . 
 개선 하 기 를 원하 는 값 비싼 쿼리 를 찾 았 으면 다음 단계 는 쿼리 를 느리 게 만드 는 것 을 이해 하 려고 시도 하 는 것 입니다 . 우리 사이트 에 개발 하 는 동안 Semalt 는 실행 하 는데 약 8 초 걸리 는 쿼리 를 발견 했 습니다 ! 
 우리 는 WooCommerce 와 사용자 정의 버전 의 WooCommerce Software Subscriptions 플러그인 을 사용 하 여 플러그인 저 장소 를 운영 합니다 . 이 쿼리 의 목적 은 고객 번호 를 알 고 있 는 고객 을 위한 모든 구독 을 얻 는 것 입니다 . 또한 소프트웨어 구독 플러그인 에서 만든 사용자 지정 테이블 에 몇 가지 조인 이 있 습니다 . 더 많 은 질문 을 이해 해 보 십시오 . 
 MySQL 은 당신 의 친구 입니다 
 meta _ id bigint 
 서명 되 지 않 은 아니 오 PRI NULL auto _ increment 
 post _ id bigint 
 서명 되 지 않 은 아니 오 MUL 0 
 meta _ key varchar ( 255 ) 예 MUL NULL 
 meta _ value 롱테일 예 NULL 
 멋지 다 . 하지만 이미 알 고 있 을지 도 모른다 . INSERT , UPDATE , REPLACE DESCRIBE 문 접두사 를 실제로 사용 할 수 있 음 을 알 고 있 습니까 ? ) 및 DELETE 문장 ? 이것 은 그 동의어 EXPLAIN 에 더 일반 적 으로 알려져 있 으며 명세서 가 어떻게 실행 될 지 에 대한 자세 한 정보 를 제공 합니다 . 
 다음 은 느린 쿼리 결과 입니다 . 
 1 단순 오후 ref post _ id , meta _ key meta _ key 576 const 37456 어디 에서 
 1 단순 p eq _ ref PRIMARY , type _ status _ date PRIMARY 8 deliciousbrainsdev . 오후 . post _ id 1 어디 에서 
 1 단순 s eq _ ref PRIMARY PRIMARY 8 deliciousbrainsdev . 엘 . key _ id 1 NULL 
 언뜻 보 기 에 는 해석 하 기 가 쉽 지 않 습니다 . 다행 스럽 게 도 Semalt 에 있 는 사람 들 은 이 성명서 를 이해 하 기 위한 포괄 적 인 안내서 를 작성 했 습니다 . 
 rows 컬럼 은 결과 를 찾 기 위해 얼마나 많 은 행 이 있 는지 를 보여 주 기 때문 에 MySQL 이 해야 할 일 을 잘 보여 줍니다 . 
 Explain 은 우리 가 최적 화 에 사용 할 수 있 는 더 많 은 정보 를 제공 합니다 . 예 를 들 어 , pm 2 테이블 ( wp _ postmeta ) 은 ORDER BY 절 을 사용 하 여 결과 를 정렬 하 도록 요청 하 기 때문 에 filesort 를 사용 하 고 있 음 을 알려 줍니다 . 쿼리 를 그룹 화 하 는 경우 실행 에 오버 헤드 가 추가 됩니다 . MySQL 5 . 6 이상 에서 실행 되 는 데이터베이스 의 경우 , EXPLAIN 의 결과 를 JSON 으로 출력 할 수 있 고 MySQL Workbench 는 JSON 을 명령문 의 시각 적 실행 계획 으로 변환 합니다 . 
 쿼리 의 일부 를 비용 별 로 색칠 하 여 자동 으로 이슈 에 주의 를 환기 시킵니다 . 우리 는 wp _ woocommerce _ software _ licences ( 별칭 l ) 테이블 에 대한 조인 이 심각 한 문제 를 가지 고 있 음 을 바로 볼 수 있 습니다 . 
 쿼리 의 일부분 은 wp _ woocommerce _ software _ licences 테이블 사이 의 조인 으로 인덱스 되 지 않 은 열 order _ id 를 사용 하 기 때문 에 전체 테이블 스캔 을 수행 하 고 있 습니다 . wp _ posts 테이블 에 추가 하 십시오 . 이 는 느린 쿼리 와 쉽 게 해결 할 수 있 는 일반 적 인 문제 입니다 . 
 order _ id 는 테이블 에서 데이터 를 식별 하 는 데 매우 중요 한 부분 이 며 , 이 와 같이 쿼리 하 는 경우 열 에 인덱스 가 있 어야 합니다 . 그렇 지 않 으면 MySQL 은 문자 그대로 테이블 의 각 행 을 스캔 합니다 . 필요 한 행 을 찾 습니다 . 인덱스 를 추가 하 고 그것 이 무엇 을 하 는지 봅시다 : 
 CREATE INDEX order _ id ON wp _ woocommerce _ software _ licences ( order _ id ) 
 와우 , 우리 는 그 인덱스 를 추가 하 여 쿼리 를 5 초 이상 면도 했 습니다 . 
 귀하 의 질의 를 알 고 
 쿼리 를 Semalt - 조인 , 서브 쿼리 로 서브 쿼리 로 조인 하 십시오 . 필요 없 는 일 을 합니까 ? 최적화 가 가능 합니까 ? 
 이 경우 우리 는 order _ id 를 사용 하 여 posts 테이블 에 licenses 테이블 을 가입 시키 며 shop _ order 유형 을 게시 하 도록 제한 합니다 . 이 는 데이터 무결 성 을 강화 하 여 올바른 주문 레코드 만 사용 하 고 있 는지 확인 하 는 것 입니다 . 그러나 실제로 는 쿼리 의 중복 부분 입니다 . 우리 는 테이블 의 소프트웨어 라이선스 행 에 posts 테이블 의 WooCommerce 순서 와 관련 된 order _ id 가 있 다는 것 이 확실 합니다 . PHP Plugin 코드 에 적용 되 어 있 기 때문 입니다 . 조 인 을 제거 하 고 사물 이 향상 되 는지 봅시다 . 
 엄청난 절약 은 아니 지만 쿼리 가 3 초 미만 입니다 . 
 모든 것 을 캐 쉬 해라 ! 
 서버 가 기본 적 으로 MySQL 쿼리 캐 싱 을 사용 하 지 않 는다면 켜 는 것 이 가치 가 있 습니다 . 즉 , MySQL 은 결과 와 함께 실행 되 는 모든 명령문 을 기록 하 고 , 동일 한 명령문 이 이어서 실행 되 면 캐시 된 결과 가 반환 됩니다 . 테이블 이 변경 될 때 MySQL 이 캐시 를 플러시 하 기 때문 에 캐시 가 오래 되 지 않 습니다 . 
 캐시 의 요청 수명 은 인 스턴스 화 된 객체 의 요청 수명 보다 더 깁니다 . 요청 전체 에서 쿼리 결과 를 지속 적 으로 유지 하 려는 경우 영구 적 인 객체 캐시 를 구현 해야 합니다 . 현명 한 데이터 는 캐시 를 설정 하 고 기본 데이터 가 변경 될 때 캐시 항목 을 무효 화 해야 합니다 . 
 Semalt 는 질 의 실행 을 빠르 게 하 고 쿼리 를 조정 하 거나 인덱스 를 추가 하 는 것 보다 더 많 은 작업 을 필요 로 하 는 다른 접근 법 입니다 . 우리 쿼리 에서 가장 느린 부분 중 하나 는 테이블 을 결합 하 여 고객 ID 에서 제품 ID 로 이동하 는 작업 입니다 . 모든 고객 을 위해 이 작업 을 수행 해야 합니다 . 단 한 번 의 가입 만 으로 도 필요 한 경우 고객 데이터 를 수집 할 수 있 습니까 ? 
 모든 라이센스 에 대한 사용자 ID 및 제품 ID 와 함께 라이센스 데이터 를 저장 하 는 테이블 을 작성 하 고 특정 고객 에 대한 데이터 를 조회 하 여 데이터 를 비 정규 화 할 수 있 습니다 . INSERT / UPDATE / DELETE 에서 MySQL 트리거 를 사용 하 여 라이센스 테이블 ( 또는 데이터 가 변경 될 수 있 는 방법 에 따라 다름 ) 에 대한 테이블 을 다시 작성 해야 하 지만 이 방법 은 해당 데이터 를 쿼리 하 는 성능 을 크 게 향상 시킵니다 . 
 마찬가지 로 여러 조 인 이 MySQL 에서 쿼리 속도 를 늦추 는 경우 쿼리 를 둘 이상 의 명령문 으로 분리 하 고 PHP 에서 별도 로 실행 한 다음 결과 를 코드 로 수집 하 고 필터링 하 는 것 이 더 빠릅니다 . Laravel 은 Eloquent 에서 열정 적 인 로드 관계 로 비슷 한 것 을 합니다 . 
 WordPress 는 많 은 양 의 데이터 와 다양 한 사용 자 정의 게시물 유형 이 있 는 경우 wp _ posts 테이블 에서 더 느린 쿼리 가 발생 할 수 있 습니다 . 게시물 유형 에 대한 쿼리 가 느린 경우 사용 자 정의 포스트 유형 스토리지 모델 에서 사용 자 정의 테이블 로 이동 하 는 것 이 좋 습니다 . 
 쿼리 최적화 에 대한 이러 한 접근 방식 을 사용 하 여 쿼리 를 8 초 에서 2 초 이상 으로 줄이 고 호출 시간 을 4 에서 1 로 줄였 습니다 . 참고 로 이러 한 쿼리 시간 은 우리 의 개발 환경 에서 실행 되 며 생산 단계 에서 더 빠를 것 입니다 . 
 이것 은 느린 쿼리 를 추적 하 고 수정 하 는 데 유용 한 가이드 가 되 기 를 바랍니다 . Semalt 최적 화 는 무서운 일 처럼 보일지 모르 지만 , 당신 이 그것 을 시도 하 고 빠른 승리 를 얻 자마자 당신 은 버그 를 얻 기 시작 할 것 이 고 , 더 나아지 기 를 원할 것 입니다 . 
 이안 폴슨 
 Iain Poulson 은 Delicious Brains 와 함께 일 하 는 영국 출신 의 WordPress 및 PHP 개발자 입니다 . 그 는 플러그인 을 만들 지 않 을 때 WordPress 와 달빛 에 관한 블로그 를 PhpStorm 전도사 로 블로그 에 올립니다 . 그 는 Delicious Brains 블로그 에서 SQL 쿼리 및 기타 고급 항목 의 속도 를 높이 는 방법 에 대해 씁니다 . https : / / deliciousbrains 에 가입 하 면 다음 단계 로 이동 합니다 . com