2017-01-25 10 views
0

У меня вопрос о том, как я могу получить все даты из всех значений MIN/MAX из нескольких столбцов и как их оптимизировать. Я пытался заставить его работать достаточно долгое время, и я почти отказался :-(MySQL - Как получить MIN/MAX Date из MIN/MAX Value

Базы данных хранит много температур от различных устройств. и структурирован таким образом.

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

а теперь я хочу, чтобы извлечь все даты и значения для MIN и MAX для каждого из измерений (дата для MIN Temp1, дата для MAX Temp1, ....)

чтобы получить Значения 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 

Для получения этих данных только требуется всего 0.2004 секунды, чтобы получить все данные из базы данных с более чем 300 000 строк.

Но поскольку мне также нужно время для MIN/MAX, я попытался с этим.

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 запросов, но это требует много времени. 1,9866 секунд для 300 000 строк.

Эти 300 000 строк представляют собой небольшую базу данных, которая рассчитывает встать примерно на 18 строк.

Я также попытался с этим одним

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

Спасибо, Юрген. Я попробую это, как только я получу время. У вас есть объяснение, почему это должно быть быстрее? Поскольку, как я вижу, это означает, что моя база данных становится несколько больше с большим количеством сообщений. Или? –

+0

Да, у вашей БД будет больше записей. Но хорошо спроектированная БД может обрабатывать даже миллиарды записей очень быстро. Поэтому не беспокойтесь о количестве записей. Беспокоитесь о хорошем дизайне. Затем БД может использовать индексы при выборе того, что делает БД быстрым. –

Смежные вопросы