2011-08-15 11 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から... 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

関連する問題