2016-03-08 53 views
0

查询优化我已经具有4列具有数百万行的表

PKID,OutMailID,JobMailingDate,InsertDatetime 这是数据OT如何插入到表 PKID是表中的主键 对于带有JObMailingDate的单个outMailID,在平均3个记录中存在与 不同的插入日期时间。该表具有数百万条记录

我有具有相同的数据,但那些被partaining不同类别

现在我想找出 1)找到许多其他表中的所有OutMailID谁InsertDatetime是参数数据范围 2)一旦我有OutMailID的名单我想找到最低InsertDatetime所有这些OutMailID如果这分钟日期落在参数1和参数2

之间

的数据表之间是这样

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 

但这种效果不理想。任何人都可以请建议我一个这样做的好方法

第二个问题是,一旦我有第一个查询的输出,然后我使用相同的上述查询其他类别来找出最小的InsertDatatime在该类别中,一旦我拥有所有的分日期为所有类别的话,我必须找到在所有类别中最小插入日期

能否请你帮我在这

感谢 阿图尔

+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子句中的所有3类别表都会使查询非常缓慢,因为CTE类似于内联查询 –

+0

您可以使用table子句执行多个操作,它将执行所有操作, t是一个性能问题,我不确定其他类别是什么,但我更新我的答案根据我的理解你想完成 –

0

此查询是否为您提供了期望的结果?

选择T.OutMailID,最小值(T.InsertDatetime) 从工作台T INNER JOIN表T1在T1.OutMailID = T.outMailID 而T2.InsertDatetime之间@参数1和参数2 @组 通过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 
       ); 

这应该使用索引的第一个子查询,限制ID的数量。它应该使用相同的索引not exists,行数减少。