2016-07-28 9 views
0

私の現在のクエリは次のようになります。私はそれを最適化しようとしてきましたが、私は今まで運がありませんでした。 私の目標は、各プレイヤーの現在の日と前日の間のstat_valueの差を取得し、それを注文することです。 現在のコードは正常に動作しますが、私には最適化されていません。 ?値はJavaを使用して入力されます。複数の行にわたるMySQLクエリの最適化

SELECT t1.stat_value - 
     (SELECT stat_value 
      FROM leaderheadsplayersdata_daily t2 
     WHERE t2.player_id = t1.player_id 
      AND t2.day = ? 
      AND t2.stat_type = ? 
     LIMIT 1 
     ) as sum 
    , (SELECT name 
      FROM leaderheadsplayers 
     WHERE leaderheadsplayers.player_id = t1.player_id 
     LIMIT 1 
     ) 
    FROM leaderheadsplayersdata_daily t1 
    WHERE day = ? 
    AND stat_type = ? 
    ORDER 
     BY sum DESC LIMIT 100 

表構造:

これは、プレイヤID及びユーザ名を含むメインテーブルです。

CREATE TABLE IF NOT EXISTS `leaderheadsplayers` 
(player_id INTEGER PRIMARY KEY AUTO_INCREMENT 
,uuid VARCHAR(36) NOT NULL UNIQUE 
,name VARCHAR(16) NOT NULL 
,last_join DATETIME 
) ENGINE = InnoDB 

これは、毎日のデータを含む表です。あなたはわずか2日間を持っているので、事前

+0

テーブル構造を記述すると、回答が示唆されます。 – evilpenguin

+0

データベース構造が追加されました。 –

+0

クエリにEXPLAINを使用した出力を提供できますか? – ultrajohn

答えて

1

CREATE TABLE IF NOT EXISTS leaderheadsplayersdata_daily 
(player_id INTEGER NOT NULL 
,stat_value DOUBLE NOT NULL 
,stat_type VARCHAR(16) NOT NULL 
,day INTEGER NOT NULL 
,FOREIGN KEY (player_id) REFERENCES leaderheadsplayers(player_id) ON DELETE CASCADE 
,PRIMARY KEY(player_id, stat_type, day) 
) ENGINE = InnoDB 

おかげで、あなたはダブルleaderheadsplayersdata_dailyテーブルに参加行うことができます。

それはこのようなものになります。

SELECT 
    p.player_id, 
    p.name, 
    (dc.stat_value-dp.statvalue) AS difference, 
    dc.day, 
FROM leaderheadsplayers p 
JOIN leaderheadsplayersdata_daily dc ON p.player_id = dc.player_id 
JOIN leaderheadsplayersdata_daily dp ON p.player_id = dp.player_id and dp.day = (dc.day-1) 
WHERE dc.day = ?CURRENT_DAY? 
ORDER BY difference DESC 

"日付電流" の略ですdcを。 dpは「前の日付」を表します。 pは「プレーヤー」を表します。

パフォーマンスを向上させるには、列にインデックスplayer_id(両方の表内)とdayを追加します。

申し訳ありませんが、私は文法エラーやものがあるかどうか試していませんでした。また、実際の日で?CURRENT_DAY?を交換してくださいと

を必要に応じてORDER BY difference DESCが動作しない場合は、WHERE句で他の条件を追加し、ちょうどORDER BY (dc.stat_value-dp.statvalue) DESCを行います。

サブクエリがたくさんあります。documentation about JOINsをご覧ください。彼らは本当に便利です。

+0

ありがとうございました。クエリは今すぐ信じられないほど速いです。 –

+0

喜んでサービスします。 :) – evilpenguin

-1

また、以下を試すこともできます。明示的なトリプル・ジョインを使用する、上記で提案されたものと暗黙のトリプル・ジョイント料金を使用するこのバージョンがどのように使用されているかを教えてください。ありがとう。

SELECT t3.player_id, improvement FROM 
    (SELECT t1.player_id as player_id, (t1.stat_value - t2.stat_value) as improvement 
     FROM leaderheadsplayersdata_daily t1 INNER JOIN leaderheadsplayersdata_daily t2 
     on t1.player_id = t2.player_id and t1.stat_type = t2.stat_type 
      and t2.day = ? and t1.day = ?) as t3 
    INNER JOIN leaderheadsplayers on 
     t3.player_id = leaderheadsplayers.player_id 
      ORDER BY improvement DESC LIMIT 100;