Отдельный запрос для получения событий на основе критериев И отдельных событий, которые приходят после каждого? - PullRequest
1 голос
/ 02 мая 2019

У нас есть таблица, в которой хранятся события (оповещения на основе машинного обучения).Каждое предупреждение содержит некоторую информацию о возможных будущих сбоях.Предупреждения, которые удовлетворяют некоторым критериям, являются специальными, и запланированное техническое обслуживание запланировано, чтобы избежать будущих сбоев на основе информации из такого предупреждения.

Схема таблицы похожа на:

|id|fin|datetime|failure|
-------------------------
|1 |fin1|2016-04-02|0|
|2 |fin1|2016-05-02|1|
|3 |fin2|2017-05-02|0|
|4 |fin2|2017-05-12|0|
|5 |fin2|2017-05-01|1|
|6 |fin3|2017-12-01|1|

, где fin описываетчасть, которая потерпела неудачу или может потерпеть неудачу в ближайшем будущем, и failure является двоичной и указывает, является ли событие предупреждением или фактическим отказом (нам нужны оба в одной таблице).

Теперь нам нужно получитьвсе оповещения, которые помечены как плановое техническое обслуживание, а также следующий сбой после каждого такого оповещения (для того же FIN, конечно, как FIN оповещения).

Примечание у нас есть ids тех предупреждений, которые помечены как плановое техническое обслуживание из другой таблицы на основе другого процесса оценки.Вы можете считать это заданным, например, в списке planned_ids (например, этот список может быть [1,3], чтобы соответствовать приведенным выше образцам данных)

Прямо сейчас мы решаем эту проблему, делая несколько запросов в БД (mysql но не так важно), сначала получить все события, которые помечены как плановое обслуживание (у нас есть ids этих событий), используя, например,

select *
from events
where id in [planned_ids]
order by datetime asc -- we dont mind if this is ordered desc as well

Затем для каждого такогооповещение, мы получаем следующую ошибку для той же FIN (функциональной части), которая приходит сразу после этого события и является ошибкой.Например, с помощью:

-- using $alert as kind of variable here to denote that the query
-- runs for each alert based on that same alert data i.e datetime and fin part
select *
from events
where fin=$alert.fin and datetime>=$alert.datetime and failure=1
order by datetime desc
limit 0,1

Это работает, но является разновидностью N+1 проблемы .

Можем ли мы получить предупреждения, а также один следующийошибка для каждого предупреждения в одном запросе sql?

1 Ответ

1 голос
/ 02 мая 2019

Коррелированный подзапрос, возможно:

select e.*,
       (select e2.id
        from events e2
        where e2.fin = e.fin and e2.datetime > e.datetime
        order by e2.datetime desc
        limit 1
       ) as next_event_id
from events e
where e.id in ( . . . )

Если вам нужна дополнительная информация, вы можете использовать ее как подзапрос и присоединиться к таблице events.

select p.*, nexte.*
from (select e.*,
             (select e2.id
              from events e2
              where e2.fin = e.fin and e2.datetime > e.datetime
              order by e2.datetime desc
              limit 1
             ) as next_event_id
      from events e
      where e.id in ( . . . )
     ) p left join
     events nexte
     on nexte.id = p.next_event_id;

Согласно документации MySQL по выполнению коррелированных запросов указано:

В некоторых случаях коррелированный подзапрос оптимизируется.Например:

val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)

В противном случае они неэффективны и могут быть медленными.Переписывание запроса как объединения может повысить производительность.

Также в соответствии с этой статьей :

Мы показали, что при некоторых обстоятельствах коррелированные подзапросыможет быть лучше, чем массовая агрегация.В Oracle.С наборами данных малого и среднего размера.В других случаях это не так, поскольку размер M и N, наши две алгоритмические переменные сложности увеличиваются, O (M log N) будет намного хуже, чем O (M + N).

ТакжеКажется, что-то вроде N+1 проблема все еще существует (, хотя с точки зрения производительности она менее серьезна, чем N отдельные запросы ), даже если использовать коррелированные подзапросы для создания одного запроса для извлечения наших данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...