이 글은 주로 MySql SQL 최적화 기술 공유를 소개하고 있습니다. 매우 훌륭하고 참고할만한 가치가 있습니다. 필요한 친구들이 참고할 수 있습니다.
어느 날 실행이 되었지만 내부 조인이 있는 SQL을 발견했습니다. 속도는 그다지 느리지는 않지만(0.1~0.2) 이상적인 속도에 도달하지 않습니다. 두 테이블은 서로 관련되어 있으며, 관련된 필드는 기본 키이고, 쿼리된 필드는 고유 인덱스입니다.
sql은 다음과 같습니다.
SELECT p_item_token.*, p_item.product_type FROM p_item_token INNER JOIN p_item ON p_item.itemid = p_item_token.itemid WHERE p_item_token.token ='db87a780427d4d02ba2bd49fac8xxx';
여기서 p_item_token 테이블의 itemid는 기본 키이고 token은 고유 인덱스입니다. p_item의 itemid가 기본키입니다
이상적인 속도에 따르면 0.03초 정도가 되어야 합니다. 그러나 실제 값은 약 0.2로 훨씬 느립니다.
계획을 직접 보려면 설명
EXPLAIN SELECT p_item_token.*, p_item.product_type FROM p_item_token INNER JOIN p_item ON p_item.itemid = p_item_token.itemid WHERE p_item_token.token = 'db87a780427d4d02ba2bd49fac8xxx';
결과:
주의하세요 위의 큰 빨간색 상자에. p_item 테이블에는 2w개의 데이터가 있으므로 전체 테이블 스캔입니다.
그건 정상이 아니네요.
공연 경고를 추가하고 살펴보세요. 참고: 어떤 경우에는 SHOW WARNINGS에 결과가 없습니다. 아직 이유를 모르겠습니다. 로컬 테스트 데이터베이스로 실행하는 것이 좋습니다.
EXPLAIN SELECT p_item_token.*, p_item.product_type FROM p_item_token INNER JOIN p_item ON p_item.itemid = p_item_token.itemid WHERE p_item_token.token = 'db87a780427d4d02ba2bd49fac8xxx'; SHOW WARNINGS;
결과 2에는 code=1003이 표시됩니다. 그 뒤에는 SQL 문이 있습니다. 이 명령문은 규칙에 따라 우리가 입력한 SQL 문을 다시 작성한 후 MySQL이 실행하는 마지막 명령문입니다.
아아앙이상해요. 어디에 CONVERT가 있는 이유는 무엇입니까? where 조건, 즉 쿼리할 필드에서 방정식의 좌변에 함수가 있으면 속도 저하가 발생한다는 것을 우리는 알고 있습니다. (제가 이해한 바: 인덱스를 더 이상 사용하지 않기 때문에 속도가 느립니다. 인덱스의 값은 원래 값인데 이 상태에서 처리된 값을 사용합니다.)
이 기능에 주의하세요, itemid를 변경하라는 의미입니다. 즉, 이 열의 인코딩은 utf8mb4가 아닙니다.
테이블을 열고 itemid 열의 인코딩을 변경하세요. 두 테이블 모두 utf8로. 다시 설명을 실행하세요.
해석 결과로 볼 때 문제는 없습니다.
결과 2의 명령문을 살펴보세요.
/* select#1 */ SELECT '0000eb612d78407a91a9b3854ffffffff' AS `itemid`, /*注:直接按主键把值查出来了*/ 'db87a780427d4d02ba2bd49fac8cf98b' AS `token`, '2016-12-16 10:46:53' AS `create_time`, '' AS `ftoken`, `p_db`.`p_item`.`product_type` AS `product_type` FROM `p_db`.`p_item_token` JOIN `p_db`.`p_item` WHERE ( ( CONVERT ( `p_db`.`p_item`.`itemid` USING utf8mb4 ) = '0000eb612d78407a91a9b3854fffffff' ) )
이 선택은 모두 상수입니다. 더 빠를 수 있나요?
실행 결과는 0.036초입니다. 기대에 부응
경험 요약:
설명 실행 계획이 기대에 부합하는지 확인할 수 있습니다. 큰 행이 있으면 전체 테이블 스캔이 발생했음을 의미합니다. 앞으로 성능 병목 현상이 발생할 것입니다
경고 결과를 표시하면 옵티마이저가 처리한 명령문을 볼 수 있습니다. 원래 진술과 불일치가 있는 경우 주의 깊게 비교하고 연구하면 실제 문제를 밝힐 수 있습니다.
이상은 MySql SQL 최적화 기법의 그래픽 코드에 대한 자세한 소개입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!