2012-05-29 3 views
1

У меня здесь немного странное. Я использую Entity Framework Code First в консольном приложении, которое запускает пакетный процесс. Код циклически повторяет цикл дат, выполняющий хранимую процедуру каждый раз.Время выполнения 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 делает это (я использую Nlog а)

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 зр –

+0

таблица, которая постепенно становится все больше именно та вещь, которая будет генерировать такое поведение вы наблюдаете. Это может помочь предоставить код 'CalculateWeightings' в случае, если сообщество SO может помочь выявить неэффективность там. – mellamokb

+0

@Romil Я вернусь к вам, это не очень сложно, поэтому я был бы удивлен, если бы это была проблема –

ответ

0

Я думаю, что эта проблема может быть связана с тем, что ваш график отслеживания EF становится слишком большим. Если вы повторно используете свой контекст в пакетной операции с графиком отслеживания при каждом выполнении операции, ему необходимо перечислить граф. С несколькими элементами hundread это не проблема, но когда вы попадаете в 000s, это может стать серьезной проблемой. Взгляните на мою статью об этом here и посмотрите, считаете ли вы, что она соответствует этой проблеме.

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

enter image description here

Смежные вопросы