Optimize entity framework query

前端 未结 5 1402
星月不相逢
星月不相逢 2020-12-02 12:27

I\'m trying to make a stackoverflow clone in my own time to learn EF6 and MVC5, i\'m currently using OWin for authentication.

Everything works fine when i have like

5条回答
  •  有刺的猬
    2020-12-02 13:25

    Take a look at section 8.2.2 of this document from Microsoft:

    8.2.2 Performance concerns with multiple Includes

    When we hear performance questions that involve server response time problems, the source of the issue is frequently queries with multiple Include statements. While including related entities in a query is powerful, it's important to understand what's happening under the covers.

    It takes a relatively long time for a query with multiple Include statements in it to go through our internal plan compiler to produce the store command. The majority of this time is spent trying to optimize the resulting query. The generated store command will contain an Outer Join or Union for each Include, depending on your mapping. Queries like this will bring in large connected graphs from your database in a single payload, which will acerbate any bandwidth issues, especially when there is a lot of redundancy in the payload (i.e. with multiple levels of Include to traverse associations in the one-to-many direction).

    You can check for cases where your queries are returning excessively large payloads by accessing the underlying TSQL for the query by using ToTraceString and executing the store command in SQL Server Management Studio to see the payload size. In such cases you can try to reduce the number of Include statements in your query to just bring in the data you need. Or you may be able to break your query into a smaller sequence of subqueries, for example:

    Before breaking the query:

    using (NorthwindEntities context = new NorthwindEntities()) {
    var customers = from c in context.Customers.Include(c => c.Orders)
                    where c.LastName.StartsWith(lastNameParameter)
                    select c;
    
    foreach (Customer customer in customers)
    {
        ...
    } }
    

    After breaking the query:

    using (NorthwindEntities context = new NorthwindEntities()) {
    var orders = from o in context.Orders
                 where o.Customer.LastName.StartsWith(lastNameParameter)
                 select o;
    
    orders.Load();
    
    var customers = from c in context.Customers
                    where c.LastName.StartsWith(lastNameParameter)
                    select c;
    
    foreach (Customer customer in customers)
    {
        ...
    } }
    

    This will work only on tracked queries, as we are making use of the ability the context has to perform identity resolution and association fixup automatically.

    As with lazy loading, the tradeoff will be more queries for smaller payloads. You can also use projections of individual properties to explicitly select only the data you need from each entity, but you will not be loading entities in this case, and updates will not be supported.

提交回复
热议问题