다음과 같은 문제가 있습니다.
원래 데이터베이스 인 Database_1과 변경 사항이 거의없는 첫 번째 데이터베이스 (일부 새 열, 다른 데이터)를 기반으로하는 Database_2가 있습니다.
데이터베이스에서 3 개의 테이블을 포함하는 쿼리를 실행하면 매우 다른 성능 결과를 얻습니다. 동일한 localhost 서버에서 두 데이터베이스를 테스트했습니다.
질문:
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `applicants` AS `Applicant`
LEFT JOIN `authake_users` AS `User` ON (`Applicant`.`authake_user_id` = `User`.`id`)
LEFT JOIN `projects` AS `Project` ON (`Project`.`applicant_id` = `Applicant`.`id`)
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL;
쿼리 실행 시간 :
Database_1 – 0.3 초 –이 데이터베이스는 더 빠르지 만 더 큰 데이터베이스입니다.
Database_2 – 1 분 40 초
세 테이블 모두 MyISAM 엔진을 사용하고 있습니다. 테이블 신청자 및 프로젝트에는 charset utf8이 있고 테이블 authake_users에는 charset latin1이 있습니다.
인덱스 (두 데이터베이스 모두 정확히 동일한 인덱스가 있음)를 확인하고 다시 작성하고 3 개의 테이블 모두에서 ANALYZE 및 OPTIMIZE를 사용하여 성공하지 못했습니다.
내가 찾은 유일한 차이점은 EXPLAIN 명령을 앞에 사용하여 쿼리를 실행할 때 아래에 표시됩니다.
아무도 무엇을 찾아야할지 알고 있습니까? 성능에 이러한 차이를 일으키는 원인은 무엇입니까?
MySql 쿼리 분석기는 사용 가능한 리소스 메모리를 기반으로 최적화 계획을 선택합니다. 그러나 테이블 순서와 JOIN 계획을 변경하면 더 나은 계획을 선택하는 데 도움이됩니다.
데이터베이스에 대한 액세스 권한이없고이 쿼리에서 필요한 출력을 알지 못하기 때문에 분석을 수행 할 수 없습니다. 하지만 다음은 시도해 볼 수있는 몇 가지 제안입니다.
귀하의 쿼리없이 WHERE
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `applicants` AS `Applicant`
LEFT JOIN `authake_users` AS `User`
ON `Applicant`.`authake_user_id` = `User`.`id`
AND `User`.`login` LIKE _latin1 '%1000%'
LEFT JOIN `projects` AS `Project`
ON `Project`.`applicant_id` = `Applicant`.`id`
AND `Project`.`id` IS NULL;
의 순서를 변경 JOINS
하고없이WHERE
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `authake_users` AS `User`
LEFT JOIN `applicants` AS `Applicant`
ON `Applicant`.`authake_user_id` = `User`.`id`
AND `User`.`login` LIKE _latin1 '%1000%'
LEFT JOIN `projects` AS `Project`
ON `Project`.`applicant_id` = `Applicant`.`id`
AND `Project`.`id` IS NULL;
순서를 변경하여 쿼리 JOINS
-1
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `authake_users` AS `User`
LEFT JOIN `applicants` AS `Applicant`
ON `Applicant`.`authake_user_id` = `User`.`id`
LEFT JOIN `projects` AS `Project`
ON `Project`.`applicant_id` = `Applicant`.`id`
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL;
JOINS
-2의 순서를 변경하여 쿼리
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `projects` AS `Project`
LEFT JOIN `applicants` AS `Applicant`
ON `Project`.`applicant_id` = `Applicant`.`id`
LEFT JOIN `authake_users` AS `User`
ON `Applicant`.`authake_user_id` = `User`.`id`
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL;
또한 인덱스의 이점을 완전히 얻으려면 이러한 종류의 User.login LIKE _latin1 '%1000%'
조건을 피해야합니다. 정말로 필요한 경우 이와 같은 것을 사용하는 것이 User.login LIKE _latin1 '1000%'
좋습니다.
내가 EXPLAIN
제안한 쿼리를 게시 할 수 있다면 매우 흥미로울 것 입니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다