2011-08-15 8 views
2

MySQL 쿼리를 최적화하는 데 어려움을 겪고 있습니다. 기존 데이터베이스 구조를 사용해야하지만 특정 상황에서 매우 느린 응답을 얻고 있습니다.MySQL 쿼리를 어떻게 최적화 할 수 있습니까?

내 쿼리는 다음과 같습니다의

SELECT 
    `t`.*, 
    `p`.`trp_name`, 
    `p`.`trp_lname`, 
    `trv`.`trv_prosceslevel`, 
    `trv`.`trv_id`, 
    `v`.`visa_destcountry`, 
    `track`.`track_id`, 
    `track`.`track_datetoembassy`, 
    `track`.`track_expectedreturn`, 
    `track`.`track_status`, 
    `track`.`track_comments` 
FROM 
    (SELECT 
     * 
    FROM 
     `_transactions` 
    WHERE 
     DATE(`tr_datecreated`) BETWEEN DATE('2011-07-01 00:00:00') AND DATE('2011-08-01 23:59:59')) `t` 
     JOIN 
    `_trpeople` `p` ON `t`.`tr_id` = `p`.`trp_trid` AND `p`.`trp_name` = 'Joe' AND `p`.`trp_lname` = 'Bloggs' 
     JOIN 
    `_trvisas` `trv` ON `t`.`tr_id` = `trv`.`trv_trid` 
     JOIN 
    `_visas` `v` ON `trv`.`trv_visaid` = `v`.`visa_code` 
     JOIN 
    `_trtracking` `track` ON `track`.`track_trid` = `t`.`tr_id` AND `p`.`trp_id` = `track`.`track_trpid` AND `trv`.`trv_id` = `track`.`track_trvid` AND `track`.`track_status` IN ('New','Missing_Info', 
     'En_Route', 
     'Ready_Pickup', 
     'Received', 
     'Awaiting_Voucher', 
     'Sent_Client', 
     'Closed') 
ORDER BY `tr_id` DESC 

결과는 위의에 문을 설명입니다 : '휴일'의 값이 매우에 포함 될 때까지

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 PRIMARY  <derived2> ALL  NULL NULL NULL NULL 164  Using temporary; Using filesort 

1 PRIMARY  track ALL  status_index NULL NULL NULL 4677 Using where 

1 PRIMARY  p eq_ref PRIMARY  PRIMARY  4 db.track.track_trpid 1 Using where 

1 PRIMARY  trv  eq_ref PRIMARY  PRIMARY  4 db.track.track_trvid 1 Using where 

1 PRIMARY  v eq_ref visa_code visa_code 4 db.trv.trv_visaid 1 

2 DERIVED  _transactions ALL  NULL NULL NULL NULL 4276 Using where 

쿼리 시간이 허용 마지막 track.track_status IN 절. 그런 다음 다른 쿼리의 10 배에서 15 배 정도 증가합니다.

'닫힌 상태'는 거래가 처리 된 모든 클라이언트를 나타내며 데이터베이스의 약 90 % ~ 95 %에 해당합니다.

경우에 따라 검색에 약 45 초가 소요되는 등의 문제가 있습니다. 나는 MySQL이 그보다 훨씬 더 잘할 수 있다고 확신한다. 테이블에 4000 행이 있더라도 내 쿼리가 잘못되었지만이 문을 최적화하는 방법을 찾을 수는 없다.

내가 잘못 가고있는 곳과 더 빠른 결과를 내기 위해이 쿼리를 어떻게 구현해야하는지에 대한 조언을 해주시면 감사하겠습니다.

많은 감사

+1

, 당신은 그냥이'_transactions의 t FROM ... WHERE DATE 같은 주요 질의에 넣어의't' 하위 쿼리가 필요하지 않습니다 (...) BETWEEN ... ' –

답변

1

이 시도 : 첫째

SELECT t.*, 
p.trp_name, 
p.trp_lname, 
trv.trv_prosceslevel, 
trv.trv_id, 
v.visa_destcountry, 
track.track_id, 
track.track_datetoembassy, 
track.track_expectedreturn, 
track.track_status, 
track.track_comments 
FROM 

_transactions t 
JOIN _trpeople p ON t.tr_id = p.trp_trid 
JOIN _trvisas trv ON t.tr_id = trv.trv_trid 
JOIN _visas v ON trv.trv_visaid = v.visa_code 
JOIN _trtracking track ON track.track_trid = t.tr_id 
AND p.trp_id = track.track_trpid 
AND trv.trv_id = track.track_trvid 
WHERE DATE(t.tr_datecreated) 
    BETWEEN DATE('2011-07-01 00:00:00') AND DATE('2011-08-01 23:59:59') 

    AND track.track_status IN ('New','Missing_Info','En_Route','Ready_Pickup','Received','Awaiting_Voucher','Sent_Client', 'Closed') 
    AND p.trp_name = 'Joe' AND p.trp_lname = 'Bloggs' 
ORDER BY tr_id DESC 
+0

나는 그것이 훌륭하다는 것을 말하고있다. 이제는 0.2 초 만에 실행됩니다. 내가 뭘 잘못하고 있었는지 말할 수 있니? 하위 쿼리를 제거하고 모든 조건부 쿼리를 마지막에 넣었습니다. 내 하위 쿼리는 검색 결과의 범위를 좁혀서 조인의 입력 크기를 줄이는 것이라고 생각했습니다. 아니, 분명히. – Joe

+1

당신은 절대적으로 옳습니다. 소개 한 하위 쿼리는 기본 쿼리를 실행하기 전에 상당한 시간이 걸렸습니다. – reggie

+0

의견을 주셔서 감사합니다. 하위 쿼리로 인해 왜 그렇게 느린 지 아직 확실하지 않습니다. 온라인에서 많은 사람들이 하위 쿼리를 사용하지 않고 조인 만 사용하는 것이 좋습니다. 이 방법을 권장 하시겠습니까? – Joe

관련 문제