2016-03-08 78 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,行數減少。