0

1日の時間ごとにグループ化して、いくつかの行でいくつかの平均といくつかの合計をフェッチしようとしています。さらに、追加の列をフェッチしたいのですが、1時間ごとの合計を取得するのではなく(グループ化時にフェッチされます)、その特定の日付までのすべての行の合計をフェッチしたいのです。SQLステートメントは以下に掲載されています。

私の問題は、MySQL データベースで 25,000 行を超えるクエリを実行するのに約 8 秒かかることです (CPU i5/8GB RAM)。サブセレクト ( ... AS 'rain_sum') が非常に遅くなることがわかりました。私の質問は次のとおりです。私はあまりにも複雑な方法で考えていますか? 以下のクエリと同じ結果を得る簡単な方法はありますか?

SELECT
    `timestamp_local` AS `date`,
    AVG(`one`) AS `one_avg`,
    AVG(`two`) AS `two_avg`,
    SUM(`three`) AS `three_sum`,
    (SELECT SUM(`b`.`three`)
        FROM `table` AS `b`
        WHERE `b`.`timestamp_local` <= SUBDATE(`a`.`timestamp_local`, INTERVAL -1 SECOND)
        LIMIT 0,1) AS `three_sum`
FROM  `table` AS  `a`
GROUP BY
    HOUR( `a`.`timestamp_local` ),
    DAY( `a`.`timestamp_local` ),
    MONTH( `a`.`timestamp_local` ),
    WEEK( `a`.`timestamp_local` ),
    YEAR( `a`.`timestamp_local` )
ORDER BY `a`.`timestamp_local` DESC
LIMIT 0, 24;
4

1 に答える 1

0

これらすべてのフィールドでグループ化するのではなく、より単純な (そしてより高速な) ソリューション (ここから) は次のようになります。

GROUP BY UNIX_TIMESTAMP(timestamp_local)/3600

あなたのクエリがあなたが望む結果を返すとは想像できません(あなたの要件を正しく理解していれば)。特定の時間に行がない場合、時間 < その時間のすべての行の合計を計算したいので、要件を理解しています。MySQL は空のグループを選択しません (サブクエリ部分の場合)。

私が知っているMySQLでこれを行う簡単で効率的な方法はありません。見ている範囲内のすべての可能なグループ化値を含む一時テーブルを作成することをお勧めします(おそらくループを使用)。おそらく数年前からこのテーブルを設定し、必要に応じて行を追加することができます。次に、このテーブルとテーブルを結合したままにすることができます。

MSSQL を使用している場合は、再帰 CTE を使用できますが、これはおそらく非常に遅くなります。MySQL の代替案については、これを参照するか、「mysql cte」をグーグルで検索してください。HOUR = HOUR+1再帰でこれを行う方法は、NULL 以外の値を取得するまで繰り返し同じテーブルで (左に) 結合してから停止することです。これらのそれぞれについて、合計を逆算します。

于 2012-12-28T09:21:37.083 に答える