В нашем приложении мы собираем данные о рабочих характеристиках автомобильных двигателей - в основном исходные данные о рабочих характеристиках двигателей на основе типа двигателя, транспортного средства, на котором он работает, и конструкции двигателя. В настоящее время основой для вставок новых рядов является период включения и выключения двигателя; мы отслеживаем переменные производительности, основываясь на изменении состояния двигателя с активного на неактивное и наоборот. Соответствующая таблица engineState
выглядит следующим образом:
+---------+-----------+---------------+---------------------+---------------------+-----------------+
| vehicle | engine | engine_state | state_start_time | state_end_time | engine_variable |
+---------+-----------+---------------+---------------------+---------------------+-----------------+
| 080025 | E01 | active | 2008-01-24 16:19:15 | 2008-01-24 16:24:45 | 720 |
| 080028 | E02 | inactive | 2008-01-24 16:19:25 | 2008-01-24 16:22:17 | 304 |
+---------+-----------+---------------+---------------------+---------------------+-----------------+
Для конкретного анализа мы хотели бы проанализировать содержимое таблицы, основываясь на степени детализации строк в минутах, а не на текущей основе активного / неактивного состояния механизма. Для этого мы думаем о создании простой таблицы productionMinute
со строкой для каждой минуты в периоде, который мы анализируем, и объединении таблиц productionMinute
и engineEvent
в столбцах даты и времени в каждой таблице. Поэтому, если наш период анализа с 2009-12-01 по 2010-02-28, мы создадим новую таблицу со 129 600 строками, по одной на каждую минуту каждого дня в течение этого трехмесячного периода. Первые несколько строк таблицы productionMinute
:
+---------------------+
| production_minute |
+---------------------+
| 2009-12-01 00:00 |
| 2009-12-01 00:01 |
| 2009-12-01 00:02 |
| 2009-12-01 00:03 |
+---------------------+
Соединение между таблицами будет:
FROM engineState AS es
LEFT JOIN productionMinute AS pm ON pm.production_minute >= es.state_start_time
AND pm.production_minute <= es.event_end_time
Это объединение, однако, поднимает множество экологических проблем:
- Таблица
engineState
содержит 5 миллионов строк, а таблица productionMinute
- 130 000 строк
- Когда строка
engineState
занимает более одной минуты (т. Е. Разница между es.state_start_time
и es.state_end_time
превышает одну минуту), как в случае с приведенным выше примером, существует несколько строк таблицы productionMinute
которые объединяются в одну engineState
строку таблицы
- Когда в течение данной минуты работает несколько двигателей, также как в приведенном выше примере, несколько строк таблицы
engineState
объединяются в одну строку productionMinute
При тестировании нашей логики и использовании только небольшого извлечения таблицы (один день, а не 3 месяца, для таблицы productionMinute
) на генерацию запроса уходит более часа. При исследовании этого элемента с целью повышения производительности, чтобы можно было запрашивать данные за три месяца, мы думали создать временную таблицу из таблицы engineEvent
, исключив любые данные таблицы, которые не являются критическими для анализа, и присоединение временной таблицы к таблице productionMinute
. Мы также планируем поэкспериментировать с различными объединениями, в частности, с внутренним объединением, чтобы посмотреть, улучшит ли это производительность.
Каков наилучший дизайн запроса для объединения таблиц со многими: многими отношениями между предикатами объединения, как описано выше? Какой тип соединения лучше (левый / правый, внутренний)?