2017-01-25 17 views
0

複数の列からすべてのMIN/MAX値からすべての日付を取得する方法と、最適化する方法について質問があります。 私はそれは長い時間が今のために合理的に実行するために取得しようとしました、と私はほとんどあきらめた:-(MySQL - MIN/MAX値をMIN/MAX値からフェッチする方法

データベースは、さまざまなデバイスからの温度の多くを保存します。 と、このように構成されている。

ID, User, DateTime, Temp1, Temp2, Temp3 and so on. 

そして今、私は(...、MIN TEMP1、MAX TEMP1のための日の日付)を測定ごとにMINとMAXのためのすべての日付と値を抽出したい

取得するにはMIN/MAX値は非常に簡単で高速です。

SELECT 
MIN(Modul_FremL) as Min_Temp1, 
MAX(Modul_FremL) as Max_Temp1, 
MIN(Modul_ReturL) as Min_Temp2, 
MAX(Modul_ReturL) as Max_Temp2, 
MIN(Modul_Gas) as Min_Temp3, 
MAX(Modul_Gas) as Max_Temp3, 
MIN(Modul_FB) as Min_Temp4, 
MAX(Modul_FB) as Max_Temp4, 
MIN(Modul_SB) as Min_Temp5, 
MAX(Modul_SB) as Max_Temp5, 
MIN(Temp_Kedel) as Min_Temp6, 
MAX(Temp_Kedel) as Max_Temp6, 
MIN(Temp_Central) as Min_Temp7, 
MAX(Temp_Central) as Max_Temp7, 
MIN(Temp_VVB) as Min_Temp8, 
MAX(Temp_VVB) as Max_Temp8, 
MIN(Temp_Ude) as Min_Temp9, 
MAX(Temp_Ude) as Max_Temp9 
FROM pillestat_data_1 
LIMIT 1 

このデータを取得するには、 にしてください。300,000行以上のデータベースからすべてのデータを取得するには、わずか0.2004秒かかります。

しかし、私もMIN/MAXのdatetimeが必要なので、これを試してみました。

SELECT DatoTid, MIN(Modul_FremL) as Temperatur FROM pillestat_data_1 WHERE Modul_FremL = (SELECT MIN(Modul_FremL) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Modul_FremL) as Temperatur FROM pillestat_data_1 WHERE Modul_FremL = (SELECT MAX(Modul_FremL) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Modul_ReturL) as Temperatur FROM pillestat_data_1 WHERE Modul_ReturL = (SELECT MIN(Modul_ReturL) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Modul_ReturL) as Temperatur FROM pillestat_data_1 WHERE Modul_ReturL = (SELECT MAX(Modul_ReturL) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Modul_Gas) as Temperatur FROM pillestat_data_1 WHERE Modul_Gas = (SELECT MIN(Modul_Gas) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Modul_Gas) as Temperatur FROM pillestat_data_1 WHERE Modul_Gas = (SELECT MAX(Modul_Gas) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Modul_FB) as Temperatur FROM pillestat_data_1 WHERE Modul_FB = (SELECT MIN(Modul_FB) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Modul_FB) as Temperatur FROM pillestat_data_1 WHERE Modul_FB = (SELECT MAX(Modul_FB) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Modul_SB) as Temperatur FROM pillestat_data_1 WHERE Modul_SB = (SELECT MIN(Modul_SB) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Modul_SB) as Temperatur FROM pillestat_data_1 WHERE Modul_SB = (SELECT MAX(Modul_SB) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Temp_Kedel) as Temperatur FROM pillestat_data_1 WHERE Temp_Kedel = (SELECT MIN(Temp_Kedel) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Temp_Kedel) as Temperatur FROM pillestat_data_1 WHERE Temp_Kedel = (SELECT MAX(Temp_Kedel) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Temp_Central) as Temperatur FROM pillestat_data_1 WHERE Temp_Central = (SELECT MIN(Temp_Central) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Temp_Central) as Temperatur FROM pillestat_data_1 WHERE Temp_Central = (SELECT MAX(Temp_Central) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Temp_VVB) as Temperatur FROM pillestat_data_1 WHERE Temp_VVB = (SELECT MIN(Temp_VVB) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Temp_VVB) as Temperatur FROM pillestat_data_1 WHERE Temp_VVB = (SELECT MAX(Temp_VVB) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MIN(Temp_Ude) as Temperatur FROM pillestat_data_1 WHERE Temp_Ude = (SELECT MIN(Temp_Ude) FROM pillestat_data_1 LIMIT 1) 
union all 
SELECT DatoTid, MAX(Temp_Ude) as Temperatur FROM pillestat_data_1 WHERE Temp_Ude = (SELECT MAX(Temp_Ude) FROM pillestat_data_1 LIMIT 1) 

実際には18個のクエリですが、時間がかかります。 300.000行の1.9866秒。

これらの300,000行はわずかなデータベースで、約1800万行になると予想しています。

また、私はこの1

SELECT 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_FremL = (SELECT MIN(Modul_FremL) FROM pillestat_data_1)) AS Min_DT_Temp1, MIN(Modul_FremL) AS Temp_Min_Temp1, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_FremL = (SELECT MAX(Modul_FremL) FROM pillestat_data_1)) AS Max_DT_Temp1, MAX(Modul_FremL) AS Temp_Max_Temp1, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_ReturL = (SELECT MIN(Modul_ReturL) FROM pillestat_data_1)) AS Min_DT_Temp2, MIN(Modul_ReturL) AS Temp_Min_Temp2, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_ReturL = (SELECT MAX(Modul_ReturL) FROM pillestat_data_1)) AS Max_DT_Temp2, MAX(Modul_ReturL) AS Temp_Max_Temp2, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_Gas = (SELECT MIN(Modul_Gas) FROM pillestat_data_1)) AS Min_DT_Temp3, MIN(Modul_Gas) AS Temp_Min_Temp3, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_Gas = (SELECT MAX(Modul_Gas) FROM pillestat_data_1)) AS Max_DT_Temp3, MAX(Modul_Gas) AS Temp_Max_Temp3, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_FB = (SELECT MIN(Modul_FB) FROM pillestat_data_1)) AS Min_DT_Temp4, MIN(Modul_FB) AS Temp_Min_Temp4, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_FB = (SELECT MAX(Modul_FB) FROM pillestat_data_1)) AS Max_DT_Temp4, MAX(Modul_FB) AS Temp_Max_Temp4, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_SB = (SELECT MIN(Modul_SB) FROM pillestat_data_1)) AS Min_DT_Temp5, MIN(Modul_SB) AS Temp_Min_Temp5, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Modul_SB = (SELECT MAX(Modul_SB) FROM pillestat_data_1)) AS Max_DT_Temp5, MAX(Modul_SB) AS Temp_Max_Temp5, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_Kedel = (SELECT MIN(Temp_Kedel) FROM pillestat_data_1)) AS Min_DT_Temp6, MIN(Temp_Kedel) AS Temp_Min_Temp6, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_Kedel = (SELECT MAX(Temp_Kedel) FROM pillestat_data_1)) AS Max_DT_Temp6, MAX(Temp_Kedel) AS Temp_Max_Temp6, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_Central = (SELECT MIN(Temp_Central) FROM pillestat_data_1)) AS Min_DT_Temp7, MIN(Temp_Central) AS Temp_Min_Temp7, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_Central = (SELECT MAX(Temp_Central) FROM pillestat_data_1)) AS Max_DT_Temp7, MAX(Temp_Central) AS Temp_Max_Temp7, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_VVB = (SELECT MIN(Temp_VVB) FROM pillestat_data_1)) AS Min_DT_Temp8, MIN(Temp_VVB) AS Temp_Min_Temp8, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_VVB = (SELECT MAX(Temp_VVB) FROM pillestat_data_1)) AS Max_DT_Temp8, MAX(Temp_VVB) AS Temp_Max_Temp8, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_Ude = (SELECT MIN(Temp_Ude) FROM pillestat_data_1)) AS Min_DT_Temp9, MIN(Temp_Ude) AS Temp_Min_Temp9, 
(SELECT DatoTid FROM pillestat_data_1 WHERE Temp_Ude = (SELECT MAX(Temp_Ude) FROM pillestat_data_1)) AS Max_DT_Temp9, MAX(Temp_Ude) AS Temp_Max_Temp9 
FROM pillestat_data_1 
LIMIT 1 

で試してみたが、何らかの理由で、それはすべての列では動作しません。 これは約半分の列で機能します。

ここにコードを最適化するのに役立つ人がいることを願っています。あなたがテストしたい場合は

// KIM

はSQLFIDDLEを行いました。

http://sqlfiddle.com/#!9/2b1c8f/16

+1

実際の問題はあなたのテーブルデザインです。あなたはそれを変更するために開いていますか? –

+1

テーブルにインデックスがありません。もちろんそれは遅いです。 –

+0

私はすべてオープンしています。 –

答えて

1

正規化されたテーブルのデザインは、自動的にインデックスを取得

devices table 
------------- 
id 
name 
... 


temperatures table 
------------------ 
id 
user_id 
datetime 
device_id 
temp 

外部キーになります。日付依存選択を行う場合は、datetime列の索引も追加します。そして、すべてのデバイスの最小値と最大値TMPを取得する

あなたは数百万レコードを持っている場合でも、数ミリ秒で結果を返す必要があります

select d.name, min(t.temp) as minTemp, max(t.temp) as maxTemp 
from temperratures t 
join devices d on d.id = t.device_id 
group by d.name 

を行います。

+0

Juergenに感謝します。 私は時間がかかるとすぐにこれを試してみます。 なぜこれがより速くなるべきかについての説明がありますか? 私が見ているように、それは私のデータベースがより多くの投稿でより大きくなるということです。または? –

+0

はい、あなたのDBにはさらに多くのレコードがあります。しかし、優れた設計のDBは数十億ものレコードをすばやく処理できます。だからレコード数について心配しないでください。良いデザインが心配です。次に、DBは、どのデータベースを高速化するかを選択するときにインデックスを利用することができます。 –

関連する問題