2016-06-02 3 views
0

Silex (Symfony 기반의 PHP 마이크로 프레임 워크)를 사용하여 만든 편안한 API를 호스팅하고 있습니다. this tutorial 다음에이 API는 매개 변수에 따라 json 객체를 반환합니다. 그러나 일부 쿼리 나는 다음과 같은 메시지가 얻을에서 OVH의 시간 제한 차기 너무 낮은 : 내 SQL 쿼리의 일부 있지만나머지 API로 성능이 낮고 시간 초과되었습니다

SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query

는 (최대 8 ~ 12 개 라인) 조금 긴, 그들은 그 복잡하지 않습니다 왜 성능이 그렇게 낮은 지 이해할 수 없습니다.

속도를 높이고 OVH가 시간 초과되지 않도록 할 수있는 방법이 있습니까? 전적으로 하나의 SQL 요청 (따라서 길기도 함)과 다양한 연산자 (WHERE, 여러 AND/OR, IN ...)를 사용하여 모든 항목을 쿼리합니다.

SELECT * 
FROM staff 
WHERE staff_id IN (
     SELECT host_id 
     FROM class_host 
     WHERE class_id IN (
       SELECT class_id 
       FROM class 
       WHERE classroom_id IN (
         SELECT classroom_id 
         FROM classroom 
         WHERE classroom_gps_lat BETWEEN $ARRAY_VALEUR [0] 
           AND $ARRAY_VALEUR [2] 
          AND classroom_gps_lon BETWEEN $ARRAY_VALEUR [1] 
           AND $ARRAY_VALEUR [3] 
         ) 
       ) 
     ) 
    OR staff_id IN (
     SELECT teacher_id 
     FROM class_teacher 
     WHERE class_id IN (
       SELECT class_id 
       FROM class 
       WHERE classroom_id IN (
         SELECT classroom_id 
         FROM classroom 
         WHERE classroom_gps_lat BETWEEN $ARRAY_VALEUR [0] 
           AND $ARRAY_VALEUR [2] 
          AND classroom_gps_lon BETWEEN $ARRAY_VALEUR [1] 
           AND $ARRAY_VALEUR [3] 
         ) 
       ) 
     ) 
    AND class_id IN (
     SELECT class_id 
     FROM class_teacher 
     WHERE teacher_id IN (
       SELECT staff_id 
       FROM staff 
       WHERE staff_name LIKE $QUOTEDARRAY 
       ) 
     ) 

여전히 가진 성능 문제 :

은 여기까지 영원히 걸리는 SQL 쿼리의 예입니다. 이것에

SELECT Count(*) AS COUNT 
FROM staff 
WHERE staff_id IN (SELECT host_id 
        FROM class_host 
        WHERE (class_id IN (SELECT class_id 
              FROM class 
              WHERE classroom_id IN (SELECT 
               classroom_id 
                    FROM 
               classroom 
                    WHERE 
               region_id IN ('FR')))) 
          OR staff_id IN (SELECT teacher_id 
              FROM class_teacher 
              WHERE class_id IN (SELECT class_id 
                   FROM class 
                   WHERE 
                classroom_id IN (SELECT 
                classroom_id 
                    FROM 
                classroom 
                    WHERE 
                region_id IN (SELECT 
                region_id 
                   FROM region 
                   WHERE 
                region_country_code IN ( 
                'FR')))))) 

: 내 코드는 다음에서 갔다

SELECT Count(*) AS COUNT 
FROM staff 
     JOIN class_host 
     ON staff.staff_id = class_host.host_id 
     JOIN class AS class1 
     ON class_host.class_id = class1.class_id 
     JOIN classroom AS classroom1 
     ON class1.classroom_id = classroom1.classroom_id 
     JOIN region AS region1 
     ON classroom1.region_id = region1.region_id 
     JOIN class_teacher 
     ON staff.staff_id = class_teacher.teacher_id 
     JOIN class AS class2 
     ON class_teacher.class_id = class2.class_id 
     JOIN classroom AS classroom2 
     ON class2.classroom_id = classroom2.classroom_id 
     JOIN region AS region2 
     ON classroom2.region_id = region2.region_id 
WHERE region1.region_country_code IN ('FR') 
     AND region2.region_country_code IN ('FR') 

내가 사용해야 "빨리"조인? 이러한 쿼리를 어떻게 최적화 할 수 있습니까?

편집 : MySQL의에서 배열을 EXPLAIN :

Explain from MySQL database for the query above

+0

귀하의 문제와 관련이 없지만 비스킷을 좋아하시는 분들은 * 귀하의 질문을 형식화하십시오! * 자신의 정신과 우리 모두를 위해서. – Siyual

+1

'JOIN'을 연구하십시오. 실제로 쿼리에 포함 된 모든 하위 쿼리가 필요하지 않습니다. – Siyual

+0

미래에 @Siyual 할 것입니다! 다음은 JOIN입니다. 감사합니다. 쿼리를 수정하고 어떻게 진행되는지 살펴 보겠습니다. 실제 대답이 아닌 실제로 답을 수락하는 방법을 잘 모르는 경우 –

답변

0

은 당신이 청소를 시작할 수 있도록 - 쿼리가 완료되지 않습니다. 선택 항목을 중첩하지 않으므로 속도가 빨라야합니다.

SELECT 
    staff.* 
FROM 
    staff 
    JOIN class_host ON staff.staff_id = class_host.host_id 
    JOIN class ON class_host.class_id = class.class_id 
    JOIN classroom ON classroom.classroom_id = class.classroom_id 
WHERE 
    classroom.gps_lat BETWEEN $ARRAY_VALEUR[0] AND $ARRAY_VALEUR[2] 
    AND classroom.classroom_gps_lon BETWEEN $ARRAY_VALEUR[1] AND $ARRAY_VALEUR[3]; 

일단 조인을 완료하면 설명을 사용하십시오. EXPLAIN SELECT staff.* FROM ...은 일부 인덱스가 누락되어 쿼리가 느리게 실행되는 것을 확인하는 데 도움이됩니다.

+0

감사합니다. SQL 구조에 대해 배울 점이 많습니다. 중첩 선택에 대해 생각하지 않고 쿼리를 연결 한 것뿐입니다. 이것을 시험해보고 성능이 향상되는지 확인하십시오. –

+0

'내부 결합'에 대한 설명을 보려면이 부분을 살펴보십시오. http://www.mysqltutorial.org/mysql-inner-join.aspx – Gravy

+0

성능 문제가 있습니다. 코드 포맷팅에서 이익을 얻으려고 상위 포스트 편집하기, 내가 조인을 올바르게하고 있는지 잘 모르겠다. –

관련 문제