Ms sql linq выбрать самую свежую запись

Допустим, с индексами вы разобрались. Теперь пойдем от SQL. Первый запрос выполняется долго, потому как вы берёте все записи из таблицы mainTable, а потом джойните отфильтрованные данные из двух других таблиц. Во втором случае вы сначала делаете фильтр, а потом выбираете данные, соответствующие этому фильтру. Полагаю, разница в скорости связана с этим.

Смотрим на код. У вас Left Join, а значит выбираются все записи из mainTable (даже те, которым нет соответствия в таблицах subTable1 и subTable2). С этими данными связываются данные из двух других таблиц, при этом записи из mainTable может потенциально соответствовать по несколько записей в таблице subTable1 и subTable2. (Допускаю, что возможны связи один-к-одному, но исходя из приведенного SQL этого не видно.) А это значит, что выборке данные из mainTable могут быть посчитаны несколько раз (см. упрощенный пример, где данные умножены).

Важно, кстати, отметить еще один момент: возможна ситуации, когда запись с некоторым pid есть в таблице subTable1, но нет записи с этим же pid в таблице subTable2. А значит, не ясно, что именно считать: все записи в таблице mainTable, которым есть соответствия в обеих зависимых таблицах (за определенный период), или же те, которым есть соответствие хотя бы в одной из таблиц?

Интресный момент. Если выбрать только уникальные записи (небольшая модификация первого запроса из вопроса), то вы получите количество записей в таблице mainTable:

эквивалентно:

В subTable1 пишется нормальная дата, в subTable2 пишутся год и месяц. Соответственно, фильтр по дате в subTable1 позволяет нам отфильтровать данные сильнее, чем фильтр по дате в subTable2. При этом возможны два сценария:

  • данные пишутся в таблицы subTable1 и subTable2 одновременно (допустим, там хранятся бинарные данные или большие тексты),
  • данные пишутся сначала в одну таблицу, потом — в другую и разница во времени может составлять минуты, часы или дни.

Первый сценарий сильно облегчает запросы на выборку (достаточно одного фильтра). Второй создает проблемы, которые требуется учесть. Например, запись в subTable1 сделана 31 декабря 2015 года, а соответствующая запись в subTable2 — 1 января 2016. Приведенные в вопросе SQL-запросы такие пары проигнорируют если в таблице subTable1 появилась запись за 1 января.

Пробуем построить запрос

Если связь между главной и зависимыми таблицами «один-к-одному» (как обязательная, так и обязательная на одном конце), то таблица mainTable в запросе не нужна. Во вложенном запросе выбираем максимальные даты, джойним по этим датам данные из таблицы subTable1. По ID из главной таблицы выбираем данные из subTable2. Фильтруем по максимальной дате данные из subTable2:

Если данные в таблицы subTable1 и subTable2 пишутся в один и тот же день, то запрос можно упростить:

Важно учесть, что запрос не считает записи из mainTable, которым ничего не соответствует в таблицах subTable1 и subTable2 (если связь «один-к-одному» обязательная на одном конце). Я бы рекомендовал такие записи считать отдельно, а потом суммировать результаты.

Тип связи «многие-ко-многим» между главной и зависимыми таблицами вызывает вопросы, ключевые из которых: что именно нужно посчитать (см. второй абзац в самом начале) и какая логика заложена в БД (см. третий абзац)?

Источник

Поделиться:
Нет комментариев

Добавить комментарий

Ваш e-mail не будет опубликован. Все поля обязательны для заполнения.

×
Вам будет интересно