0

まず、mySql について私が知っていることはすべて独学なので、間違っていることや非効率なことがある場合はお知らせください。このような30列以上のテーブルがあります...(実際の値は無視してください。これは、テーブルがどのように見えるかを理解するためのものです)

id  | uid  |  c1   |  c2  |  c3  |..cols 4-29...|  c30 |  time
---------------------------------------------------------------
 1  |  15  |  234  |  11  |  21  |              |  18  |  2013-01-19 00:00:00
 2  |  96  |  311  |  29  |  23  |              |  27  |  2013-01-19 00:00:00
 3  |  13  |  443  |  31  |  33  |              |  35  |  2013-01-19 00:00:00
 4  |  97  |  345  |  44  |  47  |              |  48  |  2013-01-19 00:00:00
 5  |  85  |  271  |  53  |  49  |              |  52  |  2013-01-19 00:00:00
 6  |  96  |  273  |  62  |  50  |              |  64  |  2013-01-20 00:00:00
 7  |  13  |  449  |  54  |  57  |              |  87  |  2013-01-20 00:00:00
 8  |  97  |  374  |  93  |  59  |              |  62  |  2013-01-20 00:00:00
 9  |  85  |  851  |  71  |  87  |              |  74  |  2013-01-20 00:00:00

id主キーです。uidもインデックス化されています。これは、 という別のテーブルのユーザー名と一致する各ユーザーの id 値ですuser_names。次に、30 列のデータとタイムスタンプ フィールドがあります。

テーブルは、各ユーザーの新しい値で毎日更新されます。列ごとに一定期間の最大の差を選択し、列ごとにその利益を上げた人の名前を選択する必要があります。機能するクエリがいくつかありますが、それらは遅く、非常に非効率的です。例えば:

SELECT tbl1.name as col1_name, tbl1.col1_diff, 
       tbl2.name as col2_name, tbl2.col2_diff FROM 

(SELECT pl.name, (MAX(c1)-MIN(c1)) as col1_diff FROM 
    `data_table` tbl JOIN `user_names` as pl ON tbl.pid=pl.id 
    WHERE time BETWEEN '2013-06-05 00:00:00' AND '2013-06-06 00:00:00' 
    GROUP BY pid ORDER BY col1_diff DESC LIMIT 1) as tbl1 

JOIN (SELECT pl.name, (MAX(c2)-MIN(c2)) as col2_diff FROM 
    `data_table` tbl JOIN `user_names` as pl ON tbl.pid=pl.id 
    WHERE time BETWEEN '2013-06-05 00:00:00' AND '2013-06-06 00:00:00' 
    GROUP BY pid ORDER BY col2_diff DESC LIMIT 1) as tbl2 

これにより、最初の 2 列のみの正しいデータが取得されます。例:

col1_name | col1_diff | col2_name | col2_diff
------------------------------------------------
   josh   |   4124    |   steve   |   512

結果の合計行を 1 行ではなく、列ごとに 1 行取得したいのですが、少なくともこれで作業できます。しかし、すでにこのクエリには約 0.5 秒かかり、別の列を計算するために追加するすべての結合がその時間を追加するだけで、許容できないクエリ時間が発生します。

このデータをできるだけ早くプルする方法を探しています。各派生テーブルでのユーザー名結合が確実に速度を落としていることはわかっていますが、最後に 1 つの大きな結合を使用して個々の名前をプルする方法を思いつくことができませんでした (それがそれに近づく方法でさえある場合)。各行のデータを取得するための 1 つのクエリをすばやく作成し、それを 30 回ループしようとしましたが、それは遅く、さらに効率が悪いように思えます。一日の終わりに各人の利益を計算し、それらを別のテーブルに保存することを検討しましたが、より良い解決策が必要だと感じています.

最終的にこのデータを表示するページでは、各列の上位獲得ユーザーとその獲得数を表示する必要がありますが、異なる日付範囲 (昨日、過去 7 日間、および過去 30 日間) でクエリを 3 回実行する必要があります。これにアプローチするための最善の方法についての助けや考えは大歓迎です。

4

0 に答える 0