Home > OS >  Performance issue in linq query
Performance issue in linq query

Time:05-13

I have created a linq query to join tables and to do aggregate function and it takes more than a minute and it is affecting performance when executing the query in database it takes 18 seconds Kindly help me to improve the performance of Linq query.

Code:

List<int> oStatus = new List<int> { (int)STATUS.PAID, (int)STATUS.PARTIALY_PAID, (int)STATUS.OPEN, (int)STATUS.COMPLETED };

List<int> oLocationids = (
    from loc in oTransactionContext.Location 
    join lum in oTransactionContext.LocationUserMap on loc.LocationId equals lum.LocationId
    where lum.UserId == iUserID && loc.LocationName != "Local Purchase" && loc.LocationId !=0 &&loc.IsActive==true
    select lum.LocationId
    ).ToList();

    var oPT_Det = (
        from inv in oTransactionContext.Invoice
        join loc in oTransactionContext.Location on inv.LocationId equals loc.LocationId
        where (inv.ClientId == (iClientID) && oLocationids.Contains(inv.LocationId.GetValueOrDefault()) &&
        (inv.EndTime > DateTime.UtcNow.AddMonths(-6))
        && inv.IsActive == (true) && oStatus.Contains(inv.Status.GetValueOrDefault()))
        group new { inv, loc } by new { inv.LocationId, loc.LocationName } into groupResult
        select new OverAllSales
        {
            Location = Helper.CommonHelper.ParseString(groupResult.Key.LocationName),
            InvoiceAmount = Helper.CommonHelper.ParseDecimal(groupResult.Sum(f => f.inv.TotalInvoiceAmount)),
        }
        ).ToList();

Postgresql:

SELECT
    COALESCE(SUM(inv.total_invoice_amount), 0) AS value1,
    loc.location_name                          AS metric
FROM location loc
     LEFT JOIN location_user_map LUM ON LUM.location_id = loc.location_id
     LEFT OUTER JOIN invoice inv ON inv.client_id =2 AND inv.location_id = loc.location_id
        AND inv.status IN (SELECT status_id FROM status WHERE status IN ('Paid', 'Partialy Paid', 'Open', 'Completed'))
WHERE loc.location_name NOT IN ('Local Purchase')
  AND loc.location_id != 0
  AND LUM.user_id IN ($user_ids)
  AND inv.is_active = TRUE
  AND CAST(inv.end_time AS date) > CURRENT_DATE - INTERVAL '2' MONTH
GROUP BY loc.location_name
ORDER BY value1 DESC

CodePudding user response:

This is direct translation of the SQL. Should generate similar SQL query.

var startDate = DateTime.Date.AddMonths(-2);

int clientId = ...
int userId = ...

var oStatus = new List<int> { (int)STATUS.PAID, (int)STATUS.PARTIALY_PAID, (int)STATUS.OPEN, (int)STATUS.COMPLETED };

var query = 
    from loc in oTransactionContext.Location 
    join lum in oTransactionContext.LocationUserMap on loc.LocationId equals lum.LocationId
    from inv in oTransactionContext.Invoice
        .Where(inv => inv.ClientId == clientId && inv.LocationId = loc.LocationId 
            && oStatus.Contains(inv.Status))
    where 
        loc.LocationName != "Local Purchase"
        && loc.LocationId !=0
        && lum.UserId == userId
        && inv.IsActive == true
        && inv.end_time >= startDate
    group inv by loc.LocationName into g
    select new 
    {
        Location = g.Key,
        InvoiceAmount = g.Sum(x => x.total_invoice_amount) ?? 0
    };

var oPT_Det = query.ToList();
  • Related