2012-12-31 9 views
5

私は約50msで3744行を生成するこの複雑なクエリを持っています。MYSQLクエリスローサブクエリとテンポラリテーブル

SELECT 
    srl.event_id as eid 
, srl.race_num as rnum 
, bts.boat_id as bid_id 
, srl.series_year as yr 
, srl.id as id 
, IFNULL(rfi.fleet,fleet_def) as flt_old,flt_match,s.series_id as sid 
, s.series_year as syr 
    ,IFNULL(ovr_pts,POINTS('4',IFNULL(ovr_place,place),num_start)) as points 

FROM 

(SELECT en1.boat_id,en1.boat_name,MAX(fleet) as fleet_def FROM entries en1 
JOIN series_race_list srl1 ON srl1.event_id=en1.event_id 
       AND srl1.series_year=en1.race_year 
LEFT JOIN entries_race er1 ON en1.boat_id= er1.boat_id 
          AND srl1.event_id=en1.event_id  
          AND srl1.series_year =en1.race_year 
WHERE srl1.series_id ='3' AND srl1.series_year ='2012' 
          AND en1.entry_deleted='N'  
GROUP BY boat_id) bts 

JOIN series_race_list srl LEFT JOIN series as s ON s.series_id=srl.series_id 
AND s.series_year =srl.series_year 

LEFT JOIN entries as en ON srl.event_id=en.event_id 
    AND srl.series_year =en.race_year AND bts.boat_id =en.boat_id 

LEFT JOIN entries_race er ON er.race_id= srl.event_id AND er.race_num=srl.race_num 
         AND er.yr = srl.series_year AND bts.boat_id =er.boat_id 

LEFT JOIN event_race_info as eri ON eri.race_id= srl.event_id 
    AND eri.race_num=srl.race_num AND eri.yr = srl.series_year 
    ANd er.line=eri.line  AND status REGEXP 'prelim|final' 

LEFT JOIN race_results as rr ON srl.event_id=rr.race_id 
    AND srl.race_num= rr.race_num AND srl.series_year =rr.yr 
    AND bts.boat_id= rr.boat_id AND checked_in='Y' 

LEFT JOIN race_fleet_info as rfi ON rfi.race_id= srl.event_id 
    AND rfi.yr=srl.series_year AND srl.race_num= rfi.race_num 
    AND rfi.fleet=rr.flt AND complete='Y' 

LEFT JOIN series_pts_override as spo ON srl.id =spo.id AND en.boat_id =spo.bid 

WHERE s.series_id ='3' AND s.series_year ='2012' AND approved ='Y' 

申し訳ありません。私が言ったように、このクエリは約50msで実行されます。今私は、このデータを使用して、この3744行の結果に対してクエリを実行したいと思います。すぐに私はこのようなクエリでこれを包みます

SELECT eid FROM(
    ......previous query here..... 
     ) data 

実行時間は50 msから2.5 secになります!

一時テーブルを作成しようとしましたが、それは同じでした。 (実際には、私はこの結果セットでいくつかの異なるクエリを実行する必要があるので、これは私の好みのアプローチです。

このサイトで読むこれは相関サブクエリだとは思いませんが、サブクエリは、派生テーブルの別名を持ち、一時テーブルは明らかにテーブルがあるため

は、エイリアステーブルが私の問題である作成の行為のように思える。

を、私はこれらのデータの3744行へのアクセスを取得できますか今度のペナルティはありませんか?

私が説明を投稿する方法を理解するのに役立ちます場合

長いクエリの説明:

id  select_type table  type possible_keys    key  key_len ref             rows Extra 
1  PRIMARY  <derived2> ALL  NULL      NULL  NULL  NULL             3744 
2  DERIVED  s   const PRIMARY      PRIMARY 5                1 
2  DERIVED  srl   ref  series_id,series_id_2  series_id 5                16  Using where 
2  DERIVED  <derived3> ALL  NULL      NULL  NULL  NULL             208  Using join buffer 
2  DERIVED  en   eq_ref PRIMARY,event_id,event_id_2 PRIMARY 9  race_reg_test.srl.event_id,bts.boat_id    1  Using index 
2  DERIVED  er   ref  PRIMARY,boat_id,boat_id_2 boat_id_2 5  bts.boat_id           5 
2  DERIVED  eri   eq_ref PRIMARY      PRIMARY 13  race_reg_test.srl.event_id,race_reg_test.srl.race_... 1 
2  DERIVED  rr   ref  PRIMARY,boat_id    boat_id 4  bts.boat_id           9 
2  DERIVED  rfi   eq_ref PRIMARY      PRIMARY 31  race_reg_test.srl.event_id,race_reg_test.srl.race_... 1 
2  DERIVED  spo   ref  PRIMARY      PRIMARY 8  race_reg_test.srl.id,race_reg_test.en.boat_id   1 
3  DERIVED  srl1  ref  series_id,series_id_2  series_id 5                16  Using index; Using temporary; Using filesort 
3  DERIVED  en1   ref  PRIMARY,event_id,event_id_2 PRIMARY 5  race_reg_test.srl1.event_id       11  Using where 
3  DERIVED  er1   ref  boat_id,boat_id_2   boat_id 4  race_reg_test.en1.boat_id        9  Using index 
+0

新しい情報です。私は実行時間が選択のためのちょうど偽であると思う。もっと見ると、SelectのFUNCTIONコールが主要な問題です。 phpmyAdminがなぜこのような実行時間の応答が異なるのかは分かりません。 hmmm ... – davewhirlwind

+0

このデータセットの一部をビューでカプセル化する可​​能性はありますか? –

+0

キャッシュなしフラグがオンになっている基本クエリを実行しようとします。 SELECT SQL_NO_CACHE srl.event_id ...実際にキャッシュが50ミリ秒で戻ってきていることを確認するだけです。 – Seth

答えて

0

あなたは一時テーブルを作成しようとしたと述べた、私はあなたのビューを意味するかということであればわかりません。

私はそのクエリでビューを作成し、ビューで必要なクエリを実行します。

CREATE VIEW massive_query_view AS 
SELECT 
    srl.event_id as eid 
, srl.race_num as rnum 
, bts.boat_id as bid_id 
, srl.series_year as yr 
, srl.id as id 
, IFNULL(rfi.fleet,fleet_def) as flt_old,flt_match,s.series_id as sid 
, s.series_year as syr 
    ,IFNULL(ovr_pts,POINTS('4',IFNULL(ovr_place,place),num_start)) as points 

FROM 

(SELECT en1.boat_id,en1.boat_name,MAX(fleet) as fleet_def FROM entries en1 
JOIN series_race_list srl1 ON srl1.event_id=en1.event_id 
       AND srl1.series_year=en1.race_year 
LEFT JOIN entries_race er1 ON en1.boat_id= er1.boat_id 
          AND srl1.event_id=en1.event_id  
          AND srl1.series_year =en1.race_year 
WHERE srl1.series_id ='3' AND srl1.series_year ='2012' 
          AND en1.entry_deleted='N'  
GROUP BY boat_id) bts 

JOIN series_race_list srl LEFT JOIN series as s ON s.series_id=srl.series_id 
AND s.series_year =srl.series_year 

LEFT JOIN entries as en ON srl.event_id=en.event_id 
    AND srl.series_year =en.race_year AND bts.boat_id =en.boat_id 

LEFT JOIN entries_race er ON er.race_id= srl.event_id AND er.race_num=srl.race_num 
         AND er.yr = srl.series_year AND bts.boat_id =er.boat_id 

LEFT JOIN event_race_info as eri ON eri.race_id= srl.event_id 
    AND eri.race_num=srl.race_num AND eri.yr = srl.series_year 
    ANd er.line=eri.line  AND status REGEXP 'prelim|final' 

LEFT JOIN race_results as rr ON srl.event_id=rr.race_id 
    AND srl.race_num= rr.race_num AND srl.series_year =rr.yr 
    AND bts.boat_id= rr.boat_id AND checked_in='Y' 

LEFT JOIN race_fleet_info as rfi ON rfi.race_id= srl.event_id 
    AND rfi.yr=srl.series_year AND srl.race_num= rfi.race_num 
    AND rfi.fleet=rr.flt AND complete='Y' 

LEFT JOIN series_pts_override as spo ON srl.id =spo.id AND en.boat_id =spo.bid 

WHERE s.series_id ='3' AND s.series_year ='2012' AND approved ='Y' 

次に、ビューでクエリを実行できます。

SELECT * FROM massive_query_view; 

希望を早めること。もう1つのことは、インデックスをチェックすることです。インデックスはwhere節をより速くしますが、より遅く挿入します。詳細については、MySQLがインデックスをどのように使用しているかのドキュメントを参照してください:http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

0

いくつかのことが、私が見る最大のものは、あなたの元のクエリである...

boat_idの時点で) が

はあなたがいない持っているよように直列に参加series_race_list SRL LEFT JOINのBTS btsとsrlの間に "ON"状態があり、デカルトの結果となり、恐らく大きな殺人者になるでしょう。 btsのすべてのレコードについて、srlのエントリを作成し、次にその製品をシリーズに追加します。明らかな有効な条件/キーで結合されているので、srlからseriesまでは問題ありません。

次に、「bts」にエイリアスする最も内側のクエリのmax(フリート)など、alias.field以外のフィールドがいくつかあります。さらに、MAX(艦隊)がボートIDでグループ分けされていてプライマリキーと解釈され、ユニークなのはどうして...なぜボートはそれを艦隊に変更するのでしょうか?もしそうなら、これは正確ですか?艦隊のテーブル(独自の自動シーケンスIDも持っている)を持っていれば、ボートは既存の艦隊に所有権/スポンサー船(何でも)を変えて、艦隊93から既にIDを持っている新しい艦隊に変更する47のファイルでは、47は最新の関係であったが、古い既存のIDであったにもかかわらず、あなたが本当に欲しいものですか? MAX()?

フィールドリストにovr_ptsとovr_placeの追加フィールドがあります(POINTS()関数は何ですか... statusは正規表現で、checked_inはレース結果で、レースフリート情報では完了します)最終的にwhere節で承認されましたが、インデックス最適化に役立つかもしれません。

最後に、特定の「s.series_id ...およびs.series_year ...」にWHERE句がありますクエリの最初のLEFT-JOINがあります。これは、基本的に左結合コンポーネントを取り消し、NULLを有効なオプションとして許可していないため、暗黙のINNER JOINに変換します。

いくつかの説明の後で、私はいくつかのクエリを変更することを提案するかもしれませんが、私が見ていた最大のものは、btsとseries_rate_listテーブルを結合する "ON"条件はありませんでした。

関連する問題