2012-05-29 68 views
1

我在這裏有點奇怪。我在運行批處理的控制檯應用程序中使用實體框架代碼優先。代碼每次循環執行存儲過程的一系列日期。SQL執行時間減少,代碼優先

目前它循環大約300次,隨着時間的推移,每次執行都會變得越來越慢,直到爬到最後。

我試過內存分析,這不是它。這裏是示例代碼。

_dbContext = new FooContext(); 
_barService = new BarService(new GenericRepository<Bar>(), _dbContext); 

for (var date = lastCalculatedDate.AddDays(1); date <= yesterday; date = date.AddDays(1)) 
{ 
    _barService.CalculateWeightings(date); 
} 

而且所有CalculateWeightings不會是(我使用n日誌以及)

public void CalculateWeightings(DateTime dateTime) 
{ 
    _logger.Info("Calculating weightings for {1}", dateTime); 
    Context.Database.ExecuteSqlCommand("EXEC CalculateWeightings @dateTime", new SqlParameter("@dateTime", dateTime); 
} 

存儲過程只是用填充一些記錄表格。沒有什麼複雜的,表格中最後有幾行1000行,所以問題不在

有什麼想法?

對於那些你想看到的SQL。它有點像一個巨獸,但我看不出有什麼理由會隨着時間的推移而減慢。處理的行數很低。

CREATE PROCEDURE [dbo].[CalculateWeightings] 
    @StartDate DateTime, 
    @EndDate DateTime, 
    @TradedMonthStart DateTime, 
    @InstrumentGroupId int 
AS 
BEGIN 
    ---- GET ALL THE END OF DAY PRICINGS FOR MONTHLYS ---- 
    SELECT 
    ROW_NUMBER() OVER 
        (
         PARTITION BY RawTrades.FirstSequenceItemName, 
         CONVERT(VARCHAR, RawTrades.LastUpdate, 103) 
         ORDER BY RawTrades.FirstSequenceItemName, RawTrades.LastUpdate DESC 
        ) AS [Row], 
    RawTrades.FirstSequenceItemID AS MonthId, 
    Sequences.ActualStartMonth, 
    Sequences.ActualEndMonth, 
    RawTrades.FirstSequenceItemName AS [MonthName], 
    CONVERT(VARCHAR, RawTrades.LastUpdate, 103) AS LastUpdate, 
    RawTrades.Price 
    INTO #monthly 
    FROM RawTrades 
    INNER JOIN Sequences ON RawTrades.FirstSequenceItemId = Sequences.SequenceItemId AND RawTrades.FirstSequenceId = Sequences.SequenceId 
    WHERE RawTrades.FirstSequenceID IN (SELECT MonthlySequenceId FROM Instruments WHERE InstrumentGroupId = @InstrumentGroupId) 
    AND [Action] <> 'Remove' 
    AND LastUpdate >= @StartDate 
    AND LastUpdate < @EndDate 
    AND ActualStartMonth >= @TradedMonthStart 
    ORDER BY RawTrades.FirstSequenceItemID, RawTrades.LastUpdate DESC 

    ---- GET ALL THE END OF DAY PRICINGS FOR QUARTERLYS ---- 
    SELECT 
    ROW_NUMBER() OVER 
        (
         PARTITION BY RawTrades.FirstSequenceItemName, 
         CONVERT(VARCHAR, RawTrades.LastUpdate, 103) 
         ORDER BY RawTrades.FirstSequenceItemName, RawTrades.LastUpdate DESC 
        ) AS [Row], 
    CONVERT(VARCHAR, RawTrades.LastUpdate, 103) AS LastUpdate, 
    Sequences.ActualStartMonth, 
    Sequences.ActualEndMonth, 
    RawTrades.Price 
    INTO #quarterly 
    FROM RawTrades 
    INNER JOIN Sequences ON RawTrades.FirstSequenceItemId = Sequences.SequenceItemId AND RawTrades.FirstSequenceId = Sequences.SequenceId 
    WHERE RawTrades.FirstSequenceID IN (SELECT QuarterlySequenceId FROM Instruments WHERE InstrumentGroupId = @InstrumentGroupId) 
    AND Action <> 'Remove' 
    AND LastUpdate >= @StartDate 
    AND LastUpdate < @EndDate 
    AND RawTrades.Price > 20 
    ORDER BY RawTrades.FirstSequenceItemID, RawTrades.LastUpdate DESC 

    ---- GET ALL THE END OF DAY PRICINGS FOR QUARTERLYS ---- 
    SELECT 
    ROW_NUMBER() OVER 
        (
         PARTITION BY RawTrades.FirstSequenceItemName, 
         CONVERT(VARCHAR, RawTrades.LastUpdate, 103) 
         ORDER BY RawTrades.FirstSequenceItemName, RawTrades.LastUpdate DESC 
        ) AS [Row], 
    CONVERT(VARCHAR, RawTrades.LastUpdate, 103) AS LastUpdate, 
    Sequences.ActualStartMonth, 
    Sequences.ActualEndMonth, 
    RawTrades.Price 
    INTO #seasonal 
    FROM RawTrades 
    INNER JOIN Sequences ON RawTrades.FirstSequenceItemId = Sequences.SequenceItemId AND RawTrades.FirstSequenceId = Sequences.SequenceId 
    WHERE RawTrades.FirstSequenceID IN (SELECT SeasonalSequenceId FROM Instruments WHERE InstrumentGroupId = @InstrumentGroupId) 
    AND Action <> 'Remove' 
    AND LastUpdate >= @StartDate 
    AND LastUpdate < @EndDate 
    AND RawTrades.Price > 20 
    ORDER BY RawTrades.FirstSequenceItemID, RawTrades.LastUpdate DESC 

    ---- BEFORE WE INSERT RECORDS MAKE SURE WE DON'T ADD DUPLICATES ---- 
    DELETE FROM LiveCurveWeightings 
    WHERE InstrumentGroupId = @InstrumentGroupId 
    AND CalculationDate = @EndDate 

    ---- CALCULATE AND INSERT THE WEIGHTINGS ---- 
    INSERT INTO LiveCurveWeightings (InstrumentGroupId, CalculationDate, TradedMonth, QuarterlyWeighting, SeasonalWeighting) 
    SELECT 
    @InstrumentGroupId, 
    @EndDate, 
    #monthly.ActualStartMonth, 
    AVG(COALESCE(#monthly.Price/#quarterly.Price,1)) AS QuarterlyWeighting, 
    AVG(COALESCE(#monthly.Price/#seasonal.Price,1)) AS SeasonalWeighting 
    FROM #monthly 
    LEFT JOIN #quarterly 
     ON #monthly.ActualStartMonth >= #quarterly.ActualStartMonth 
     AND #monthly.ActualEndMonth <= #quarterly.ActualEndMonth 
     AND #quarterly.[Row] = 1 
     AND #monthly.LastUpdate = #quarterly.LastUpdate 
    LEFT JOIN #seasonal 
     ON #monthly.ActualStartMonth >= #seasonal.ActualStartMonth 
     AND #monthly.ActualEndMonth <= #seasonal.ActualEndMonth 
     AND #seasonal.[Row] = 1 
     AND #monthly.LastUpdate = #seasonal.LastUpdate 
    WHERE #monthly.[Row] = 1 
    GROUP BY #monthly.ActualStartMonth 

    DROP TABLE #monthly 
    DROP TABLE #quarterly 
    DROP TABLE #seasonal 

END 
+0

分享CalculateWeightings SP –

+0

逐漸變大正是這種事情會產生什麼樣的行爲,你觀察到的表的代碼。如果SO社區可以幫助發現那裏的低效率,那麼可以提供'CalculateWeightings'的代碼。 – mellamokb

+0

@Romil我會盡快回復你,這不是很複雜,所以如果出現問題,我會感到驚訝 –

回答

0

我認爲這個問題可能是由於您的EF跟蹤圖變得太大。如果在每次執行操作時使用跟蹤圖在批處理操作中重新使用上下文,則需要枚舉該圖。通過一些簡單的項目,這不是一個問題,但是當你進入000s時,它可能成爲一個巨大的問題。看看我的文章here,看看你是否認爲它符合這個問題。

如果您查看下圖中的插入操作,您可以看到大約1000個插入(跟蹤打開時)開始在執行時間內急劇上升。 (也注意到軸上的日誌尺度)

enter image description here