2010-06-16 4 views
0

이것은 내 mysql 쿼리입니다.내 MYSQL 쿼리를 확인하고 조언 해주십시오.

SELECT s.s_nric       AS nric, 
     s.s_name       AS name, 
     s.s_psle_eng      AS psle_eng, 
     s.s_psle_math      AS psle_maths, 
     s.s_psle_aggr      AS psle_aggr, 
     (SELECT re.re_mark 
     FROM si_results re 
     WHERE re.re_code LIKE 'FEEN%' 
       AND re.re_year = '2008' 
       AND re.re_semester = '2' 
       AND re.re_nric = s.s_nric) AS english_2008, 
     (SELECT re.re_mark 
     FROM si_results re 
     WHERE re.re_code LIKE 'FEMA%' 
       AND re.re_year = '2008' 
       AND re.re_semester = '2' 
       AND re.re_nric = s.s_nric) maths_2008, 
     (SELECT re.re_mark 
     FROM si_results re 
     WHERE re.re_code LIKE 'FEEN%' 
       AND re.re_year = '2009' 
       AND re.re_semester = '2' 
       AND re.re_nric = s.s_nric) AS english_2009, 
     (SELECT re.re_mark 
     FROM si_results re 
     WHERE re.re_code LIKE 'FEMA%' 
       AND re.re_year = '2009' 
       AND re.re_semester = '2' 
       AND re.re_nric = s.s_nric) maths_2009, 
     isc.isc_g_gpa      AS isc_gpa 
FROM si_student_data AS s 
     LEFT JOIN si_isc_gpa AS isc 
     ON isc.isc_g_nric = s.s_nric 
WHERE 1 = 1 
     AND s.s_admission_year = '2008' 
GROUP BY s.s_nric 
ORDER BY s.s_gender, 
      s.s_name ASC 

이 내 하위 쿼리

(SELECT re.re_mark 
    FROM si_results re 
    WHERE re.re_code like 'FEEN%' 
    AND re.re_year='2008' 
    AND re.re_semester='2' 
    AND re.re_nric=s.s_nric) as English_2008, 
(SELECT re.re_mark 
    FROM si_results re 
    WHERE re.re_code like 'FEMA%' 
    AND re.re_year='2008' 
    AND re.re_semester='2' 
    AND re.re_nric=s.s_nric) Maths_2008, 
(SELECT re.re_mark 
    FROM si_results re 
    WHERE re.re_code like 'FEEN%' 
    AND re.re_year='2009' 
    AND re.re_semester='2' 
    AND re.re_nric=s.s_nric) as English_2009, 
(SELECT re.re_mark 
    FROM si_results re 
    WHERE re.re_code like 'FEMA%' 
    AND re.re_year='2009' 
    AND re.re_semester='2' 
    AND re.re_nric=s.s_nric) Maths_2009 

내 쿼리를 실행

이며, 서버가 실행 시간이 오래 걸릴 내 서브 쿼리를 확인하시기 바랍니다. 그래서 간단하게 만드는 방법? 제발 조언 해주세요.

감사합니다.

+0

'Maths_2009' 및 Maths_2008 이전에 쿼리에'AS '의 몇 가지 인스턴스가 누락 된 것처럼 보입니다. – Sampson

+0

알겠습니다. 하지만 이것은 선택 사항입니다. 권리? – Suba

+0

안녕하세요, 조나단, 내 질문에 이미지 파일을 첨부하는 방법을 알고 있습니까? 답장을 보내 주셔서 감사합니다. – Suba

답변

5

색인을 생성하지 않으면 LIKE 'XXXX%'을 수행하는 것이 매우 느립니다. 어떤 경우에는 영원히 걸릴 수 있습니다. 또한 조인 (join)보다는 네 개의 서브 선택 (sub select)을하고 있는데, 이는 다시 느려집니다. 아래에 동일한 결과를 생성하는 전체 쿼리를 추가했습니다. 대신 조인 수를 줄여서 쿼리의 크기를 줄이고 대신 NORMALIZED 출력을 사용할 수 있습니다. 모든 nricname에 대해 re_mark 대신 여러 행을 사용할 수 있습니다 (영어, 수학, 2008, 2009 등). 코드 (FEEN 또는 FEMA)가 포함 된 두 개의 열과 표.

다음 쿼리에게 시험을주고 당신을 위해 더 나은 작동하는지 확인 :

SELECT s.s_nric       AS nric, 
     s.s_name       AS name, 
     s.s_psle_eng      AS psle_eng, 
     s.s_psle_math      AS psle_maths, 
     s.s_psle_aggr      AS psle_aggr, 
     e_2008_feen.re_mark    AS english_2008, 
     e_2008_fema.re_mark    AS maths_2008, 
     e_2009_feen.re_mark    AS english_2009, 
     e_2009_fema.re_mark    AS maths_2009, 
     isc.isc_g_gpa      AS isc_gpa 
FROM si_student_data AS s 
INNER JOIN si_results e_2008_feen 
    ON e_2008_feen.re_code LIKE 'FEEN%' 
     AND e_2008_feen.re_year = '2008' 
     AND e_2008_feen.re_semester = '2' 
     AND e_2008_feen.re_nric = s.s_nric 

INNER JOIN si_results e_2008_fema 
    ON e_2008_fema.re_code LIKE 'FEMA%' 
     AND e_2008_fema.re_year = '2008' 
     AND e_2008_fema.re_semester = '2' 
     AND e_2008_fema.re_nric = s.s_nric 

INNER JOIN si_results e_2009_feen 
    ON e_2009_feen.re_code LIKE 'FEEN%' 
     AND e_2009_feen.re_year = '2009' 
     AND e_2009_feen.re_semester = '2' 
     AND e_2009_feen.re_nric = s.s_nric 

INNER JOIN si_results e_2009_fema 
    ON e_2009_fema.re_code LIKE 'FEMA%' 
     AND e_2009_fema.re_year = '2009' 
     AND e_2009_fema.re_semester = '2' 
     AND e_2009_fema.re_nric = s.s_nric 

LEFT JOIN si_isc_gpa AS isc 
    ON isc.isc_g_nric = s.s_nric 

WHERE s.s_admission_year = '2008' 
GROUP BY s.s_nric 
ORDER BY s.s_gender, 
      s.s_name ASC 

편집 : 포함 된 정규화 된 버전 :

:이 같은 행을 생성합니다

SELECT s.s_nric       AS nric, 
     s.s_name       AS name, 
     s.s_psle_eng      AS psle_eng, 
     s.s_psle_math      AS psle_maths, 
     s.s_psle_aggr      AS psle_aggr, 
     si_results.re_code     AS code 
     si_results.re_mark     AS mark 
     si_results.re_year     AS year 
     isc.isc_g_gpa      AS isc_gpa 

FROM si_student_data AS s 

INNER JOIN si_results e_2008_feen 
    ON si_results.re_nric = s.s_nric 

LEFT JOIN si_isc_gpa AS isc 
    ON isc.isc_g_nric = s.s_nric 

WHERE s.s_admission_year = '2008' 
    AND si_results.re_year in ('2008', '2009') 
    AND si_results.re_semester = '2' 
    AND (
      si_results.re_code LIKE 'FEEN%' 
      OR si_results.re_code LIKE 'FEMA%' 
    ) 

GROUP BY s.s_nric 
ORDER BY s.s_gender, 
      s.s_name ASC 

nric: 1 
name: 'student 1' 
psle_eng: eng1 
psle_maths: maths1 
psle_aggr: aggr1 
code: FEENXXXX 
mark: 5 
year: 2008 
isc_gpa: gpa1 



nric: 1 
name: 'student 1' 
psle_eng: eng1 
psle_maths: maths1 
psle_aggr: aggr1 
code: FEENXXXX 
mark: 3 
year: 2009 
isc_gpa: gpa1 


nric: 1 
name: 'student 1' 
psle_eng: eng1 
psle_maths: maths1 
psle_aggr: aggr1 
code: FEMAXXXX 
mark: 4.5 
year: 2008 
isc_gpa: gpa1 


nric: 1 
name: 'student 1' 
psle_eng: eng1 
psle_maths: maths1 
psle_aggr: aggr1 
code: FEMAXXXX 
mark: 5 
year: 2009 
isc_gpa: gpa1 

네 개의 레코드에 대해 변경되는 값은 code, 0입니다.및 year. 이전과 같이 4 배의 레코드 수를 얻을 수 있지만 이전보다 훨씬 빠르게 실행해야합니다. 코드는 모든 행을 반복하고 필요에 따라 집계해야합니다.

+0

안녕하세요, 감사합니다. 지금 노력하고있어. 기다려주세요 – Suba

+0

도와 주셔서 감사합니다. – Suba

+0

이름 IC ENGLISH_2008 ENGLISH_2009 MATHS_2008 MATHS_2009 ISC_GPA
xxx 1 20 40 50 55 2.25 다음과 같은 결과가 필요합니다. 나는 당신의 질문을 좋아합니다. 매우 빠릅니다. pls 조언을 내 – Suba

2

이런 식으로 뭔가를 시도 : (

  • 사용 조회수 1 :

    re1.re_mark AS english_2008, 
        re2.re_mark AS maths_2008, 
        re3.re_mark AS english_2009, 
        re4.re_mark AS maths_2009, 
        isc.isc_g_gpa AS isc_gpa 
    
    FROM si_student_data AS s 
        INNER JOIN si_results as re1 ON re1.re_code LIKE 'FEEN%' AND re1.re_year = '2008' 
          AND re1.re_semester = '2' AND re1.re_nric = s.s_nric 
        INNER JOIN si_results as re2 ON re2.re_code LIKE 'FEMA%' AND re2.re_year = '2008' 
          AND re2.re_semester = '2' AND re2.re_nric = s.s_nric 
        INNER JOIN si_results as re3 ON re3.re_code LIKE 'FEEN%' AND re3.re_year = '2009' 
          AND re3.re_semester = '2' AND re3.re_nric = s.s_nric 
        INNER JOIN si_results as re4 ON re4.re_code LIKE 'FEMA%' AND re4.re_year = '2009' 
          AND re4.re_semester = '2' AND re4.re_nric = s.s_nric  
    

    INNER가

    를 필요한 경우이 솔루션은 여전히 ​​두 더 많은 옵션이 충분하지 않으면 가입 왼쪽으로 가입 교체 당신이 가진 각 조건에 대해)

    CREATE VIEW FEEN2008 AS SELECT의 re_mark, 다시 같은 si_results FROM re_nric WHERE re.re_code LIKE 'FEEN %의' 및 re.re_year = '2008' 및 re.re_semester = '2'

    과 같은 원래 쿼리를 대체 :

    FROM si_student_data AS s 
        INNER JOIN FEEN2008 as re1 ON re1.re_nric = s.s_nric 
        INNER JOIN FEMA2008 as re2 ON re2.re_nric = s.s_nric 
        INNER JOIN FEEN2009 as re3 ON re3.re_nric = s.s_nric  
        INNER JOIN FEMA2009 as re4 ON re4.re_nric = s.s_nric 
    

    일반적으로 데이터베이스 엔진은보기를 최적화하므로 더 빠를 수 있습니다. MySql이 어떻게 작동하는지 잘 모르겠습니다.

  • 필드를 사용하여 si_results에서 인덱스를 만듭니다. re_code, re_year, re_semester 및 re_nric 이렇게하면 삽입 및 업데이트 속도가 느려집니다.

+0

안녕하세요. 기다려주세요. 당신의 도움을 주셔서 감사합니다. – Suba

+0

안녕하세요. 당신의 질문을 따릅니다. 내 기대 행 형식 및 필드 있어요. 그러나 오랜 시간이 걸립니다. – Suba

+0

Mr.Matt S 답변을 볼 수 있습니까? 매트의 질문이 좋다. 하지만 모든 필드가 한 줄로 필요합니다. Mr.Matt의 쿼리를 변경/수정할 수 있습니까? 나를 보살펴주세요. 감사합니다 – Suba

0

하위 쿼리는 항상 저에게 의심스러워합니다. 그 데이터를 얻는 다른 방법을 조사하는 것은 매우 유혹스러운 일입니다. si_results 테이블은 3 번 사용되었고 종류에 따라 왼쪽 조인으로 다시 쓸 좋은 후보로 붉은 깃발이 나에게 제기됩니다. 하지만 3000 열만 있으면 속도가 느려지지 않아야합니다.

대신 하위 쿼리를 제거하고 성능을 다시 확인하십시오. 아마도 정말로 필요한 것은 새로운 색인 일 것입니다.

+0

이름 IC ENGLISH_2008 ENGLISH_2009 MATHS_2008 MATHS_2009 ISC_GPA
xxx 1 20 40 50 55 2.25 다음과 같은 신고가 필요합니다. – Suba

관련 문제