0

ワークアウトデータ、エクササイズ、セットテーブルの3つのテーブルを持つMySQLデータベースに取り組んでいます。これら 3 つのテーブルに基づくレポートの生成に関連する問題に直面しています。

さらに情報を追加すると、いくつかのセットがエクササイズを構成し、いくつかのエクササイズがワークアウトになります. 現在、これらのテーブルのデータからレポートを生成するための指標があります。今週を含む過去 42 日間のレポートを作成する必要があります。これらのテーブルを結合してレポートを取得するまでに、クエリは長時間実行されます。

たとえば、sets テーブルには、過去 42 日間だけで 100 万件を超えるレコードがあります。このテーブルの ID は、exercise テーブルの excercise_id です。エクササイズ テーブルの ID は、workout_data テーブルの運動 ID です。

このクエリを実行していますが、データを取得するのに 10 分以上かかります。レポートを作成し、ブラウザでユーザーに表示する必要があります。しかし、この実行時間の長いクエリが原因で Web ページがタイムアウトし、ユーザーはレポートを表示できません。

これを達成する方法について何かアドバイスはありますか?

        SELECT REPORTSETS.USER_ID,REPORTSETS.WORKOUT_LOG_ID,
               REPORTSETS.SET_DATE,REPORTSETS.EXCERCISE_ID,REPORTSETS.SET_NUMBER 
          FROM EXCERCISES 
    INNER JOIN REPORTSETS ON EXCERCISES.ID=REPORTSETS.EXCERCISE_ID 
         where user_id=(select id from users where email='testuser1@gmail.com') 
           and substr(set_date,1,10)='2013-10-29' 
      GROUP BY REPORTSETS.USER_ID,REPORTSETS.WORKOUT_LOG_ID,
               REPORTSETS.SET_DATE,REPORTSETS.EXCERCISE_ID,REPORTSETS.SET_NUMBER
4

4 に答える 4

1

2つのこと:

まず、次の WHERE 句の項目を使用して、1 日のデータを引き出します。

  AND substr(set_date,1,10)='2013-10-29'

これは、日付にインデックスを使用することを決定的に無効にします。set_date列にDATETIMEデータ型がある場合、必要なのは

  AND set_date >= `2013-10-09`
  AND set date <  `2013-10-09` + INTERVAL 1 DAY

これにより、set_date のインデックスでレンジ スキャンを使用できるようになります。に複合インデックスが必要なようです(user_id, set_date)。しかし、EXPLAINそれが正しいかどうかを判断するには、 をいじる必要があります。

第二に、あなたは を誤用していますGROUP BYSUM()またはのような何らかの集計関数がGROUP_CONCAT()クエリに含まれていない限り、その句は無意味です。欲しいORDER BYですか?

于 2013-11-01T13:57:38.180 に答える
1

調べたい SQL に関するコメント:

1) USER_ID と SET_DATE にインデックスはありますか?

2) SET_DATE のデータ型が間違っているように見えます。varchar ですか? 日付として保存すると、データベースが検索をより効率的に最適化できることを意味します。現時点では、部分文字列メソッドは、where 句の最初の部分によって返されるすべての行に対して実行する必要があるため、クエリごとに数え切れないほど呼び出されます。

3) group by は本当に必要ですか? 私が何かを見逃していない限り、ステートメントの「グループ化」部分は何もテーブルにもたらしません;)

于 2013-11-01T13:52:30.563 に答える
0

日付を日付として、または比較に必要な形式で保存できれば、大きな違いが生じるはずです。すべての日付で substr() 呼び出しを実行すると、時間がかかります。

于 2013-11-01T13:52:06.733 に答える
-1

確かに、クエリのチューニングに関する提案は、クエリの速度を向上させるのに役立ちます. しかし、ここでの要点は、セッションがタイムアウトする前に100 万以上のレコードで何ができるかということだと思います。200 万から 300 万のレコードがある場合、パフォーマンスを調整することで問題が解決するでしょうか? 私はそうは思わない。そう:

1) ブラウザに表示したい場合は、ページネーションを使用して、(たとえば) 最初の 100 レコードをクエリします。
2) レポート (pdf など) を生成する場合は、非同期メソッド (JMS) を使用します。

于 2013-11-01T13:44:17.907 に答える