2016-03-08 1 views
0

У меня есть таблица, которая имеет 4 колонкиОптимизация запросов с миллионами строки в таблице

PKID, OutMailID, JobMailingDate, InsertDatetime Это, как данные OT вставляется в таблицу PKID является первичным ключом таблицы для одного outMailID с JObMailingDate есть на avg 3 записи присутствуют в таблице с разные даты вставки даты. Таблица имея миллионы записей

У меня есть много другой таблицы, которая имеет одни и те же данные, но те, как partaining к другой категории

Теперь я хотел бы выяснить 1) Найти все OutMailID Чьей InsertDatetime в между данными параметров диапазона 2) После того, как у меня есть список OutMailID Я хотел бы найти минимум InsertDatetime для всех этих OutMailID Где эта мин Дата падает между Param 1 и Param2

данные для таблицы, как это

Select 1 as PKID,1 as OutMailID,'2010/01/01' as JobMailingDate,'2010/01/01' as InsertDatetime 
UNION ALL 

Select 2 as PKID,1 as OutMailID,'2010/01/01' as JobMailingDate,'2010/01/02' as InsertDatetime 
UNION ALL 

Select 3 as PKID,1 as OutMailID,'2010/01/01' as JobMailingDate,'2010/01/03' as InsertDatetime 
UNION ALL 

Select 4 as PKID,1 as OutMailID,'2010/01/01' as JobMailingDate,'2010/01/04' as InsertDatetime 

Все вышеупомянутые 2 шага я хочу, чтобы выполнить в одном запросе так что мой запрос somethig как этот

Select 
    OutMailID,Min(InsertDatetime) 
from 
    Table T 
    INNER JOIN 
    (
     Select 
      OutMailID 
     from 
      Table 
     Where 
      InsertDatetime Between @Param1 and @Param2 
    ) as T1 On (T1.OutMailID = T.outMailID) 
Group by 
    OutMailID 
Having Min(InsertDatetime) Between Between @Param1 and @Param2 

Но это не очень хорошо. может кто-нибудь предложить мне хороший способ сделать это?

Вторая проблема заключается в том, что как только у меня будет выход первого запроса, то я использую тот же самый запрос для другой категории, чтобы узнать min InsertDatatime в этой категории и один раз есть вся мин даты для всех категории, то я должен найти Min вставки дату среди всех категории

Может ли вы помочь мне в этом

Благодарности Атула

+0

Я бы пошел с инструкцией 'with' для выполнения более высокой производительности на этом –

+1

Отметьте свой вопрос в базе данных, которую вы используете. Как можно было бы подозревать, фактический двигатель важен как соображение эффективности. –

+0

Вы также должны добавить определение используемых таблиц (как 'create table') все индексы, определенные (как' create index') и план выполнения (в виде простого текста, пожалуйста, скриншоты скрывают слишком много деталей) –

ответ

0

Как об использовании на этом with , with как вид, что держит все в кэше, чтобы его позже, вот пример

with Table1 as (
    Select OutMailID from Table Where InsertDatetime Between @Param1 and @Param2 
), 
Table2 as (
    Select 4 as PKID,1 as OutMailID,'2010/01/01' as JobMailingDate,'2010/01/04' as InsertDatetime 
) 
select * from Table as T 
inner join Table1 as T1 on T1.OutMailID = T.outMailID 
group by T.OutMailID 

Таким образом, вы можете повторно использовать Table1 несколько раз без повторного запроса снова.

+0

Поскольку я должен выполнить тот же шаг с другой категорией, так что наличие всей таблицы трех категорий в предложении tablle сделает запрос очень медленным, потому что CTE похож на встроенный запрос. –

+0

Вы можете сделать несколько с предложением table, которое будет выполнять все как один раз, t проблема с производительностью, я не уверен, что другие категории, но я обновляю свой ответ на основе того, что, как я понимаю, вы хотите достичь –

0

Получает ли этот запрос желаемые результаты?

Выберите T.OutMailID, Мин (T.InsertDatetime) из таблицы T INNER JOIN Таблица T1 = О T1.OutMailID T.outMailID И T2.InsertDatetime между @ Param1 и @ Param2 Группа по OutMailID

0

Я думаю, что более простой способ выразить свое требование состоит в том, что вы хотите все OutMailId, чьи первые InsertDateTime в указанный период.

Оказалось, что для этого не требуется JOIN. Это упрощенная версия запроса:

Select t.OutMailID, Min(InsertDatetime) 
from Table T 
Group by OutMailID 
Having Min(InsertDatetime) Between @Param1 and @Param2; 

Многие базы данных могут воспользоваться индексом на Table(OutMailId, InsertDateTime) для этого запроса.

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

select t.* 
from (select OutMailId, min(InsertDatetime) as min_InsertDatetime 
     from table t 
     where InsertDatetime Between @Param1 and @Param2 
     group by OutMailId 
    ) t 
where not exists (select 1 
        from table t2 
        where t2.OutMailId = t.OutMailId and 
         t2.InsertDateTime < @Param1 
       ); 

Это должно использовать индекс для первого подзапроса, ограничивая число идентификаторов. Он должен использовать тот же индекс для not exists, при уменьшенном числе строк.