2011-12-29 3 views
0

이상한 문제가있어서 원인을 파악하는 데 도움이 필요합니다. 지금까지 나는 증상을 관찰 할 수만있었습니다. "보이는 것"은 MySQL이 처음 "LEFT JOIN"전에 개행 문자가 있는지 여부에 따라 다른 쿼리를 실행한다는 것입니다. 내가 www.xeround.com에서 제공하는 MySQL 데이터베이스 인스턴스에 대한 쿼리를 실행하고공백이 MySQL Left Join에 영향을주고 NULL 값을 반환하는 이유는 무엇입니까?

:

여기 내 설정입니다. 나는 Kohana 프레임 워크, 버전 3.0을 사용하고 있습니다. Lighttpd에서 PHP 5.3.3 FastCGI를 실행하고 있습니다. 나는 MySQL의 기본 드라이버로 PHP를 컴파일 :

--with-mysql을 = mysqlnd --with-mysqli = mysqlnd --with-PDO-mysql을 = mysqlnd

내가 기본 Kohana 3 MySQL 데이터베이스 드라이버를 사용하고 및 QueryBuilder.

PHP 코드를 건너 뛰고 SQL을 공유하기 때문에 문제가 될 것 같습니다. 이 같은 결과를 반환

SELECT `fieldreps`.`user_id` AS `fieldreps.user_id`, `fieldreps`.`availability_id` AS `fieldreps.availability_id`, `fieldreps`.`applicant_type` AS `fieldreps.applicant_type`, `fieldreps`.`license_number` AS `fieldreps.license_number`, `fieldreps`.`license_exp` AS `fieldreps.license_exp`, `fieldreps`.`license_state` AS `fieldreps.license_state`, `fieldreps`.`car` AS `fieldreps.car`, `fieldreps`.`authorized_worker` AS `fieldreps.authorized_worker`, `fieldreps`.`restrictions` AS `fieldreps.restrictions`, `fieldreps`.`night` AS `fieldreps.night`, `fieldreps`.`day` AS `fieldreps.day`, `fieldreps`.`longer` AS `fieldreps.longer`, `fieldreps`.`commitment` AS `fieldreps.commitment`, `fieldreps`.`travel_metro` AS `fieldreps.travel_metro`, `fieldreps`.`travel_states` AS `fieldreps.travel_states`, `fieldreps`.`big_employee` AS `fieldreps.big_employee`, `fieldreps`.`employed` AS `fieldreps.employed`, `fieldreps`.`retail` AS `fieldreps.retail`, `fieldreps`.`status` AS `fieldreps.status`, `fieldreps`.`start` AS `fieldreps.start`, `fieldreps`.`sales` AS `fieldreps.sales`, `fieldreps`.`study` AS `fieldreps.study`, `fieldreps`.`relevant` AS `fieldreps.relevant`, `fieldreps`.`experience` AS `fieldreps.experience`, `fieldreps`.`claims` AS `fieldreps.claims`, `fieldreps`.`education` AS `fieldreps.education`, `fieldreps`.`degree_details` AS `fieldreps.degree_details`, `fieldreps`.`degree_institution` AS `fieldreps.degree_institution`, `fieldreps`.`other_training` AS `fieldreps.other_training`, `fieldreps`.`jobs` AS `fieldreps.jobs`, `fieldreps`.`current_training` AS `fieldreps.current_training`, `fieldreps`.`interested` AS `fieldreps.interested`, `fieldreps`.`achievements` AS `fieldreps.achievements`, `fieldreps`.`passions` AS `fieldreps.passions`, `fieldreps`.`ambitions` AS `fieldreps.ambitions`, `fieldreps`.`max_travel_time` AS `fieldreps.max_travel_time`, `fieldreps`.`creation_time` AS `fieldreps.creation_time`, `fieldreps`.`resume` AS `fieldreps.resume`, `users`.`user_id` AS `users.user_id`, `users`.`email` AS `users.email`, `users`.`name` AS `users.name`, `users`.`password` AS `users.password`, `users`.`given_name` AS `users.given_name`, `users`.`title` AS `users.title`, `users`.`nationality` AS `users.nationality`, `availabilities`.`availability_id` AS `availabilities.availability_id`, `availabilities`.`fieldrep_id` AS `availabilities.fieldrep_id`, `availabilities`.`mon_start` AS `availabilities.mon_start`, `availabilities`.`mon_end` AS `availabilities.mon_end`, `availabilities`.`tue_start` AS `availabilities.tue_start`, `availabilities`.`tue_end` AS `availabilities.tue_end`, `availabilities`.`wed_start` AS `availabilities.wed_start`, `availabilities`.`wed_end` AS `availabilities.wed_end`, `availabilities`.`thur_start` AS `availabilities.thur_start`, `availabilities`.`thur_end` AS `availabilities.thur_end`, `availabilities`.`fri_start` AS `availabilities.fri_start`, `availabilities`.`fri_end` AS `availabilities.fri_end`, `availabilities`.`sat_start` AS `availabilities.sat_start`, `availabilities`.`sat_end` AS `availabilities.sat_end`, `availabilities`.`sun_start` AS `availabilities.sun_start`, `availabilities`.`sun_end` AS `availabilities.sun_end` FROM `fieldreps` AS `fieldreps` LEFT JOIN `users` ON (`fieldreps`.`user_id` = `users`.`user_id`) LEFT JOIN `availabilities` ON (`fieldreps`.`availability_id` = `availabilities`.`availability_id`) 

: :이 QueryBuilder이 쿼리 구축 끝 (. 나는 대부분의 필드가 짧고 적은 개인을 유지하기 위해 Fieldreps 테이블에서 반환 제거)를

[0] => Array 
    (
     [fieldreps.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad 
     [fieldreps.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456 
     [fieldreps.car] => Yes 
     [fieldreps.authorized_worker] => Yes 
     [fieldreps.restrictions] => Has Restrictions: No 
     [fieldreps.night] => Yes 
     [fieldreps.day] => Yes 
     [fieldreps.longer] => Yes 
     [users.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad 
     [users.email] => [email protected] 
     [users.name] => Jones 
     [users.password] => 
     [users.given_name] => Fred 
     [users.title] => Miss 
     [users.nationality] => 
     [availabilities.availability_id] => 
     [availabilities.fieldrep_id] => 
     [availabilities.mon_start] => 
     [availabilities.mon_end] => 
     [availabilities.tue_start] => 
     [availabilities.tue_end] => 
     [availabilities.wed_start] => 
     [availabilities.wed_end] => 
     [availabilities.thur_start] => 
     [availabilities.thur_end] => 
     [availabilities.fri_start] => 
     [availabilities.fri_end] => 
     [availabilities.sat_start] => 
     [availabilities.sat_end] => 
     [availabilities.sun_start] => 
     [availabilities.sun_end] => 
    ) 
[1] => Array 
    (
     [fieldreps.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41 
     [fieldreps.availability_id] => 
     [fieldreps.car] => 1 
     [fieldreps.authorized_worker] => 1 
     [fieldreps.restrictions] => 
     [fieldreps.night] => 1 
     [fieldreps.day] => 1 
     [fieldreps.longer] => 1 
     [users.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41 
     [users.email] => [email protected] 
     [users.name] => Smith 
     [users.password] => 
     [users.given_name] => Jill 
     [users.title] => 
     [users.nationality] => 
     [availabilities.availability_id] => 
     [availabilities.fieldrep_id] => 
     [availabilities.mon_start] => 
     [availabilities.mon_end] => 
     [availabilities.tue_start] => 
     [availabilities.tue_end] => 
     [availabilities.wed_start] => 
     [availabilities.wed_end] => 
     [availabilities.thur_start] => 
     [availabilities.thur_end] => 
     [availabilities.fri_start] => 
     [availabilities.fri_end] => 
     [availabilities.sat_start] => 
     [availabilities.sat_end] => 
     [availabilities.sun_start] => 
     [availabilities.sun_end] => 

내가 처음 LEFT 직전에 개행 문자를 삽입 할 때, 다음과 같이 가입 :

SELECT `fieldreps`.`user_id` AS `fieldreps.user_id`, `fieldreps`.`availability_id` AS `fieldreps.availability_id`, `fieldreps`.`applicant_type` AS `fieldreps.applicant_type`, `fieldreps`.`license_number` AS `fieldreps.license_number`, `fieldreps`.`license_exp` AS `fieldreps.license_exp`, `fieldreps`.`license_state` AS `fieldreps.license_state`, `fieldreps`.`car` AS `fieldreps.car`, `fieldreps`.`authorized_worker` AS `fieldreps.authorized_worker`, `fieldreps`.`restrictions` AS `fieldreps.restrictions`, `fieldreps`.`night` AS `fieldreps.night`, `fieldreps`.`day` AS `fieldreps.day`, `fieldreps`.`longer` AS `fieldreps.longer`, `fieldreps`.`commitment` AS `fieldreps.commitment`, `fieldreps`.`travel_metro` AS `fieldreps.travel_metro`, `fieldreps`.`travel_states` AS `fieldreps.travel_states`, `fieldreps`.`big_employee` AS `fieldreps.big_employee`, `fieldreps`.`employed` AS `fieldreps.employed`, `fieldreps`.`retail` AS `fieldreps.retail`, `fieldreps`.`status` AS `fieldreps.status`, `fieldreps`.`start` AS `fieldreps.start`, `fieldreps`.`sales` AS `fieldreps.sales`, `fieldreps`.`study` AS `fieldreps.study`, `fieldreps`.`relevant` AS `fieldreps.relevant`, `fieldreps`.`experience` AS `fieldreps.experience`, `fieldreps`.`claims` AS `fieldreps.claims`, `fieldreps`.`education` AS `fieldreps.education`, `fieldreps`.`degree_details` AS `fieldreps.degree_details`, `fieldreps`.`degree_institution` AS `fieldreps.degree_institution`, `fieldreps`.`other_training` AS `fieldreps.other_training`, `fieldreps`.`jobs` AS `fieldreps.jobs`, `fieldreps`.`current_training` AS `fieldreps.current_training`, `fieldreps`.`interested` AS `fieldreps.interested`, `fieldreps`.`achievements` AS `fieldreps.achievements`, `fieldreps`.`passions` AS `fieldreps.passions`, `fieldreps`.`ambitions` AS `fieldreps.ambitions`, `fieldreps`.`max_travel_time` AS `fieldreps.max_travel_time`, `fieldreps`.`creation_time` AS `fieldreps.creation_time`, `fieldreps`.`resume` AS `fieldreps.resume`, `users`.`user_id` AS `users.user_id`, `users`.`email` AS `users.email`, `users`.`name` AS `users.name`, `users`.`password` AS `users.password`, `users`.`given_name` AS `users.given_name`, `users`.`title` AS `users.title`, `users`.`nationality` AS `users.nationality`, `availabilities`.`availability_id` AS `availabilities.availability_id`, `availabilities`.`fieldrep_id` AS `availabilities.fieldrep_id`, `availabilities`.`mon_start` AS `availabilities.mon_start`, `availabilities`.`mon_end` AS `availabilities.mon_end`, `availabilities`.`tue_start` AS `availabilities.tue_start`, `availabilities`.`tue_end` AS `availabilities.tue_end`, `availabilities`.`wed_start` AS `availabilities.wed_start`, `availabilities`.`wed_end` AS `availabilities.wed_end`, `availabilities`.`thur_start` AS `availabilities.thur_start`, `availabilities`.`thur_end` AS `availabilities.thur_end`, `availabilities`.`fri_start` AS `availabilities.fri_start`, `availabilities`.`fri_end` AS `availabilities.fri_end`, `availabilities`.`sat_start` AS `availabilities.sat_start`, `availabilities`.`sat_end` AS `availabilities.sat_end`, `availabilities`.`sun_start` AS `availabilities.sun_start`, `availabilities`.`sun_end` AS `availabilities.sun_end` FROM `fieldreps` AS `fieldreps` 
LEFT JOIN `users` ON (`fieldreps`.`user_id` = `users`.`user_id`) LEFT JOIN `availabilities` ON (`fieldreps`.`availability_id` = `availabilities`.`availability_id`) 

나는 지금 내가 원하는 결과를 얻을 :

[0] => Array 
    (
     [fieldreps.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad 
     [fieldreps.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456 
     [fieldreps.car] => Yes 
     [fieldreps.authorized_worker] => Yes 
     [fieldreps.restrictions] => Has Restrictions: No 
     [fieldreps.night] => Yes 
     [fieldreps.day] => Yes 
     [fieldreps.longer] => Yes 
     [users.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad 
     [users.email] => [email protected] 
     [users.name] => Jones 
     [users.password] => 
     [users.given_name] => Fred 
     [users.title] => Miss 
     [users.nationality] => 
     [availabilities.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456 
     [availabilities.fieldrep_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad 
     [availabilities.mon_start] => 540 
     [availabilities.mon_end] => 1020 
     [availabilities.tue_start] => 540 
     [availabilities.tue_end] => 1020 
     [availabilities.wed_start] => 540 
     [availabilities.wed_end] => 1020 
     [availabilities.thur_start] => 540 
     [availabilities.thur_end] => 1020 
     [availabilities.fri_start] => 540 
     [availabilities.fri_end] => 1020 
     [availabilities.sat_start] => 
     [availabilities.sat_end] => 
     [availabilities.sun_start] => 
     [availabilities.sun_end] => 
    ) 
[1] => Array 
    (
     [fieldreps.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41 
     [fieldreps.availability_id] => 
     [fieldreps.car] => 1 
     [fieldreps.authorized_worker] => 1 
     [fieldreps.restrictions] => 
     [fieldreps.night] => 1 
     [fieldreps.day] => 1 
     [fieldreps.longer] => 1 
     [users.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41 
     [users.email] => [email protected] 
     [users.name] => Smith 
     [users.password] => 
     [users.given_name] => Jill 
     [users.title] => 
     [users.nationality] => 
     [availabilities.availability_id] => 
     [availabilities.fieldrep_id] => 
     [availabilities.mon_start] => 
     [availabilities.mon_end] => 
     [availabilities.tue_start] => 
     [availabilities.tue_end] => 
     [availabilities.wed_start] => 
     [availabilities.wed_end] => 
     [availabilities.thur_start] => 
     [availabilities.thur_end] => 
     [availabilities.fri_start] => 
     [availabilities.fri_end] => 
     [availabilities.sat_start] => 
     [availabilities.sat_end] => 
     [availabilities.sun_start] => 
     [availabilities.sun_end] => 

사용자 테이블의 LEFT JOIN은 두 시나리오에서 모두 잘 작동합니다. 나는 또한 첫 번째가 아닌 두 번째 LEFT JOIN 전에 개행을 추가하려고 시도했다. 원하지 않는 결과. 내가 고칠 수있는 유일한 방법은 처음 LEFT JOIN 앞에 줄 바꿈을하는 것입니다. QueryBuilder에 의해 작성되고 MySQL로 보내진 질의는 항상 길고, 한 줄짜리, 최소한의 공백 줄입니다 ... 새 줄은 없습니다! 이 문제가 발생한 것은 이번이 처음입니다. 첫 번째 LEFT JOIN 전에 개행을 배치해야한다는 요구를 믿을 수 없습니다.

내 질문은 이러한 점에 귀결 :

  1. 이 이런 식으로 일이있을 건가요? (쿼리 결과에 영향을 미치는 공백)
  2. 내가 원하는 결과를 얻는 가장 좋은 방법은 무엇입니까?

저는 SQL 전문가가 아니기 때문에이 질문을하지 않아도됩니다. 나는 내가 바라보고있는 것이 있다는 것을 확신합니다.

조나단에게 감사

생각처럼 내 문제는 바로 내 앞에 있었다

답변

0

:

지수

내가 실수 availabilities.fieldrep_id에 두 개의 인덱스를 생성 한

하고, 스키마의 나머지 부분에 대한 인덱스는 최고였습니다.

3 개의 조인 중 2 개에 대해 인덱스를 사용하지 않고 있음을 나타내는 EXPLAIN을 사용했습니다. 나는 나의 색인을 정리했고, 지금은 언제나 훌륭하게 작동합니다.

또한, 내가 왜 줄 바꿈이 쿼리를 변경하는지 알 것 같아요. 쿼리를 반복해서 실행하면 개행을 추가했는지 여부에 관계없이 주어진 예제 사이를 전환 할 수 있습니다. MySQL에 반복 쿼리를위한 캐싱이 있다고 가정합니다. 나는 개행 문자가 캐시 된 버전을 무시하기에 충분하기 때문에 때로는 원하는 결과를 얻을 수 있다고 생각한다.

문제는 색인과 관련이 있습니다. 다른 모든 것은 단지 증상이었습니다.

아마도 누군가가 약간의 시간을 절약하는 데 도움이 될 것입니다.

관련 문제