2017-08-07 4 views
0

実際にテーブルには、データが時間単位で処理された後、暫定ベースでサンプリングされた電気メーターの処理データが含まれており、processed_data_hourlyテーブルに挿入されています。どのように私は、指定された期間の消費を計算するために、このMySQLクエリを調整することができますか?

は、今私が何をしたいのか私が欲しい期待される出力を

クエリ下

processed_data_hourlyテーブルから顧客選択した日付と時刻の期間ごとにレポートを表示を与えているが、それは約70を実行するために多くの時間を要し〜90秒。

だから、誰もが実行時間が少ない

Query : 

    SELECT 
     A.node_id, 
     A.start_time, 
     B.end_time, 
     A.startReadingIMP, 
     B.endReadingIMP, 
     (B.endReadingIMP - A.startReadingIMP) diffIMP 
    FROM 
     ((SELECT 
     node_id, start_time, end_time, srv_vah startReadingIMP 
    FROM 
     processed_data_hourly 
    WHERE 
     start_time >= '2017-05-15 00:00:00' 
      AND end_time <= '2017-05-15 23:59:59' 
    GROUP BY node_id 
    ORDER BY start_time ASC) AS A, (SELECT 
     node_id, start_time, end_time, erv_vah endReadingIMP 
    FROM 
     processed_data_hourly 
    WHERE 
     start_time >= '2017-05-15 00:00:00' 
      AND end_time <= '2017-05-15 23:59:59' 
    GROUP BY end_time DESC) AS B 
    ) 
    WHERE 
     A.node_id = 6 and B.node_id=6 

    GROUP BY A.node_id , B.node_id 

の予想される出力になるように、私はこのクエリを最適化するのに役立ちます。 Output

テーブル構造

Table Structure

PS:たくさんの列が含まれているため、テーブルの構造が大きすぎて投稿できない

+1

もしあなたが望む結果が得られたら、それは幸運なことです。https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.htmlでこれを読んでください。テーブル定義を含むように質問を編集し、テキストとしてのテストデータ、クエリの説明、およびあなたが何をしようとしているのかを記述すると役に立ちます –

+0

ラッキー?それは奇跡です。 – Strawberry

+0

このクエリで実際に何をしようとしていますか? – Strawberry

答えて

0

まず第一に、このスニペットでは、あなたのクエリに構文エラーがあります:group byリストの後

WHERE 
     start_time >= '2017-05-15 00:00:00' 
      AND end_time <= '2017-05-15 23:59:59' 
    GROUP BY end_time DESC) AS B 
    ) 

DESC句は許可されていません。

代わりにGROUP BY node_id ORDER BY end_time DESCであるはずです。


私quessが正しければ、その後、私の第二の発言は、あなたのクエリがMySQL Group by extenstionを使用していることです。ドキュメントによると:ONLY_FULL_GROUP_BYが無効になっている場合

、GROUP BYの標準 SQLの使用にMySQLの拡張状態を有する、選択リストを許可、または偶数列場合非集約列を参照するには、リストBY ORDER は機能的にGROUP BY列に依存しません。これにより、MySQL は上記のクエリを受け入れます。この場合、サーバーはフリーであるため、 は各グループから任意の値を選択します。したがって、同じ値でなければ、 の値は不確定です。これはおそらくあなたが望むものではありません。 さらに、各グループからの値の選択は、ORDER BY句の追加によって影響される にはなりません。結果セットの並べ替えは、値が選択された後に が発生し、ORDER BYは、サーバーが選択する各グループ内の値 に影響しません。 ONLY_FULL_GROUP_BYを無効にすると、データの一部の プロパティによって、GROUP BYに指定された ではない非集約列のすべての値が各グループで同じであることがわかっている場合に役立ちます。


ワン実際にあなたのクエリは、テーブルからランダムに行を選んでいることを言うかもしれません。
あなたはこの簡単なデモでいることを観察することができます:あなたは上記の結果を分析する場合SQLFiddle

SELECT * FROM processed_data_hourly; 

| node_id |   start_time |    end_time | srv_vah | erv_vah | 
|---------|----------------------|----------------------|---------|---------| 
|  6 | 2017-05-15T00:01:00Z | 2017-05-15T00:14:00Z |  11 |  111 | 
|  6 | 2017-05-15T00:05:00Z | 2017-05-15T00:12:00Z |  22 |  222 | 
|  6 | 2017-05-15T00:04:00Z | 2017-05-15T00:13:00Z |  33 |  333 | 
|  6 | 2017-05-15T00:07:00Z | 2017-05-15T00:10:00Z |  44 |  444 | 
|  6 | 2017-05-15T00:08:00Z | 2017-05-15T00:21:00Z |  55 |  555 | 

SELECT 
     A.node_id, 
     A.start_time, 
     B.end_time, 
     A.startReadingIMP, 
     B.endReadingIMP, 
     (B.endReadingIMP - A.startReadingIMP) diffIMP 
    FROM 
     ((SELECT 
     node_id, start_time, end_time, srv_vah startReadingIMP 
    FROM 
     processed_data_hourly 
    WHERE 
     start_time >= '2017-05-15 00:00:00' 
      AND end_time <= '2017-05-15 23:59:59' 
    GROUP BY node_id 
    ORDER BY start_time ASC) AS A, (SELECT 
     node_id, start_time, end_time, erv_vah endReadingIMP 
    FROM 
     processed_data_hourly 
    WHERE 
     start_time >= '2017-05-15 00:00:00' 
      AND end_time <= '2017-05-15 23:59:59' 
    GROUP BY node_id 
    ORDER BY end_time DESC) AS B 
    ) 
    WHERE 
     A.node_id = 6 and B.node_id=6 
    GROUP BY A.node_id , B.node_id 

| node_id |   start_time |    end_time | startReadingIMP | endReadingIMP | diffIMP | 
|---------|----------------------|----------------------|-----------------|---------------|---------| 
|  6 | 2017-05-15T00:01:00Z | 2017-05-15T00:14:00Z |    11 |   111 |  100 | 

、あなたはbothsサブクエリは最初の行を選んだことを見ることができ、それは次のとおりです。

| node_id |   start_time |    end_time | srv_vah | erv_vah | 
|---------|----------------------|----------------------|---------|---------| 
|  6 | 2017-05-15T00:01:00Z | 2017-05-15T00:14:00Z |  11 |  111 | 

これは本当にあなたが望む結果であるならば、あなたはid, start_timeでテーブルを注文し、別の一つにクエリを書き換え、各idのために最初の行だけを選んで、のようなものができます。

SELECT node_id, 
     start_time, 
     end_time, 
     srv_vah As startReadingIMP, 
     erv_vah As endReadingIMP, 
     erv_vah - srv_vah As diffIMP 
FROM processed_data_hourly a 
WHERE NOT EXISTS (
    SELECT * 
    FROM processed_data_hourly b 
    WHERE a.node_id = b.node_id 
    AND b.start_time < a.start_time 
); 

| node_id |   start_time |    end_time | startReadingIMP | endReadingIMP | diffIMP | 
|---------|----------------------|----------------------|-----------------|---------------|---------| 
|  6 | 2017-05-15T00:01:00Z | 2017-05-15T00:14:00Z |    11 |   111 |  100 | 

デモ:http://sqlfiddle.com/#!9/8faefc/5

は、

次に、node_id, start_timeにインデックスを追加すると、このクエリは非常に高速になるはずです。

関連する問題