私は、オンザフライで計算する必要があるデータを表示しようとすると少し厄介ですが、SELECTがあります。非常に遅いサブクエリを使用して選択を最適化する
データはSmartHomeシステムから記録され、可視化ソリューションGrafanaに表示されます。 私はこのすべてをMySQLで処理しなければならず、この作業の一部を行うためにデータやフロントエンドを実際に編集することはできません。
図には、UIで選択できる時間範囲の1日あたりの平均温度が表示されます。 MySQLで データはそのようなテーブルです:
DEVICE | READING | VALUE | TIMESTAMP
-----------------------------------------------------------------------------
Thermometer | temperature | 20.0 | 2107.10.12 00:12:59
Thermometer | temperature | 20.2 | 2107.10.12 00:24:12
...
要求は、最初の約10年ごとに完全な時間のタイムスタンプで(つまり、データベースにない)仮想テーブルを作成します。 これは非常に速く実行されていて、遅いフェッチの理由ではないようです。
その後、私は仮想テーブルを私のダイアグラムの可視時間範囲内の値に細分化します。 これらのフルタイム・タイムスタンプのすべてで、サブ・セレクトを実行して1時間前に記録された最後の温度値を取得する必要があります。
この値は、1日ごとにグループ化され、平均値が計算されます。 そのようにして、00:00から23:00までの1時間ごとの平均値は24以上になります。 異なる湿度場に基づいて、これは公式平均温度が通常計算される方法です。
SELECT
filtered.hour as time,
AVG((SELECT VALUE
FROM history
WHERE READING="temperature" AND DEVICE="Thermometer" AND TIMESTAMP <= filtered.hour
ORDER BY TIMESTAMP DESC
LIMIT 1
)) as value
FROM (
SELECT calculated.hour as hour FROM (
SELECT DATE_ADD(DATE_SUB(DATE($__timeTo()), INTERVAL 10 YEAR), INTERVAL t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i HOUR) as hour
FROM (SELECT 0 as i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 as i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 as i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 as i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
(SELECT 0 as i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4
) calculated
WHERE calculated.hour >= $__timeFrom() AND calculated.hour <= $__timeTo()
) filtered
GROUP BY DATE(filtered.hour)
図を表示することが既に約5〜10秒かかり週のタイムスパンの場合:
はここでSELECT文です。あなたは1ヶ月近く30分近くです。 他のすべての(計算のない単純なフェッチ)ダイアグラムは、約1秒以内に読み込まれます。
私は完全にMySQLのnoobであり、自分のスマートな家のためにいくつかのSELECTを作成し始めたので、これをどう改善できるかは本当に分かりません。
プロの意見はありますか? :)
これは間違いなく答えですが、特定の時系列データベースを使用する必要がありますか? Graphite https://graphiteapp.org/には統計機能があり、Influxdb(https://www.influxdata.com/time-series-platform/influxdb/)にはSQLのような構文があり、またプロメテウスなどがあります。そのようなソリューションの優れた点 - メトリックを扱うために設計されたもので、mysqlよりも長い時間をクエリするとずっと速くなります –
1日に24回測定する必要がありますか? –
@PeterM私は測定の量がそれほど重要でないとは思わない。私は6以上のものは良い結果を与えるべきだと思う、それは正式な計算からあまり変わらない。 大きな問題は、1日に等間隔でなければならないということです。さもなければ、あなたはたぶん、夜や1日を重くしすぎて、偽の結果をもたらすでしょう。 これは、フルタイムのタイムスタンプで「仮想テーブル」を作成した理由です。 – Thyraz