Linq query causing performance Issue

Indudhar Gowda 426 Reputation points
2022-12-21T16:08:24.55+00:00
    foreach (DictionaryEntry ID in IDs)  
      {  
         int qWorkID = int.Parse(ID.Value.ToString());   
     var QWF = (from qwf in Model.QWorkflowSet  
         where qwf.QWorkID == qWorkID  
          select qwf).FirstOrDefault();  
          QWF.ClaimedBy = ClaimedBy;  
          QWF.ReleaseTypeID = 177;  
           QWF.ClaimedDt = ClaimedDt;      
    	   }  
        Model.SaveChanges();  

Above Linq is causing performance Issue...Not sure FirstOrDefault is causing this..

var QWF = (from qwf in Model.QWorkflowSet
where qwf.QWorkID == qWorkID
select qwf).FirstOrDefault();

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,415 questions
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,681 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,288 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,306 questions
{count} votes

Accepted answer
  1. Viorel 112.5K Reputation points
    2022-12-23T10:12:40.923+00:00

    Maybe the problem is caused by multiple SQL queries that are performed inside the loop. Check if it is possible to do something like this:

    var ids = IDS.Values.Select( id => Convert.ToInt32( id)).ToList( );  
    foreach( var qwf in Model.QWorkflowSet.Where( w => ids.Contains( w.QWorkID))  
    {  
       qwf.ClaimedBy = ClaimedBy;  
       qwf.ReleaseTypeID = 177;  
       qwf.ClaimedDt = ClaimedDt;      
    }  
    Model.SaveChanges();  
    

    Adjust it according to details.

    There is an alternative: to define a stored procedure in SQL and pass all of the values to execute a single UPDATE statement.

    2 people found this answer helpful.

4 additional answers

Sort by: Most helpful
  1. Karen Payne MVP 35,196 Reputation points
    2022-12-22T01:12:30.733+00:00

    This should be a comment but it's too long. In Visual Studio project, create a new text file with .sql extension.

    Get column details, replace Customers with your table name.

    SELECT c.name 'Column Name',  
           t.name 'Data type',  
           c.max_length 'Max Length',  
           c.precision,  
           c.scale,  
           c.is_nullable,  
           ISNULL(i.is_primary_key, 0) 'Primary Key'  
    FROM sys.columns c  
        INNER JOIN sys.types t  
            ON c.user_type_id = t.user_type_id  
        LEFT OUTER JOIN sys.index_columns ic  
            ON ic.object_id = c.object_id  
               AND ic.column_id = c.column_id  
        LEFT OUTER JOIN sys.indexes i  
            ON ic.object_id = i.object_id  
               AND ic.index_id = i.index_id  
    WHERE c.object_id = OBJECT_ID('Customers');  
    

    Another .sql file to get table indices

    SELECT   
         TableName = t.name,  
         IndexName = ind.name,  
         IndexId = ind.index_id,  
         ColumnId = ic.index_column_id,  
         ColumnName = col.name,  
         ind.*,  
         ic.*,  
         col.*   
    FROM   
         sys.indexes ind   
    INNER JOIN   
         sys.index_columns ic ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id   
    INNER JOIN   
         sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id   
    INNER JOIN   
         sys.tables t ON ind.object_id = t.object_id   
    WHERE   
         ind.is_primary_key = 0   
         AND ind.is_unique = 0   
         AND ind.is_unique_constraint = 0   
         AND t.is_ms_shipped = 0   
    ORDER BY   
         t.name, ind.name, ind.index_id, ic.is_included_column, ic.key_ordinal;  
    

    These quires may help determine the problem.

    1 person found this answer helpful.

  2. Bruce (SqlWork.com) 56,931 Reputation points
    2022-12-21T16:13:38.26+00:00

    Most likely you are missing an index. Use Sql profiler and query analyzer.


  3. PatriceSc 166 Reputation points
    2022-12-21T16:54:27.84+00:00

    Hi,

    I assume QWorkID is unique and you expect a single row ? You are not using eager loading ? I would use Count() to see how many rows are available from this table, would perhaps try a a quick repro of something similar and would report back to those in charge of the db.

    FirstOrDefault should do a SELECT TOP 1 to get either the first row or no row at all. BTW how do you see your issue is here in particular(rather than maybe on SaveChanges ?)


  4. PatriceSc 166 Reputation points
    2022-12-22T15:58:12.503+00:00

    IMO stop trying random changes. If you don't have access to the db, talk with your DBA. If you don't have an index on QWorkID, the db server must scans the whole table (which is why I wanted to understand if this table is storing 10, 100, millions or even a higher number of rows). The DBA could also try a query in this table and have tools to see if it performs as expected on his side...

    Yes, it can be other stuff such as having columns with huge content(s), using eager loading for related tables etc... but it's likely best to start with usual suspects and close doors before moving to the next possible issue.

    BTW I assume it happens only here and that you do have other similar queries causing no issue at all ?