2015-04-24 19 views
5

Sto cercando di capire perché è il mio caso più veloce di istruzioni che utilizzano la proprietà di navigazione. Ho due domande.Entity framework performance join vs navigation property

Prima con proprietà di navigazione:

  var result = (from users in context.MetricBloodPreasure 
       orderby users.User.LastName, users.User.FirstName 
       select new 
       { 
        UserName = users.User.LastName + ", " + users.User.FirstName, 
        Date = users.DateOfValue, 
       }).ToList(); 

Generatet sql:

SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[C2] AS [C2], 
    [Project1].[DateOfValue] AS [DateOfValue] 
    FROM (SELECT 
     [Extent1].[DateOfValue] AS [DateOfValue], 
     [Extent2].[FirstName] AS [FirstName], 
     [Extent2].[LastName] AS [LastName], 
     1 AS [C1], 
     CASE WHEN ([Extent2].[LastName] IS NULL) THEN N'' ELSE [Extent2].[LastName] END + N', ' + CASE WHEN ([Extent2].[FirstName] IS NULL) THEN N'' ELSE [Extent2].[FirstName] END AS [C2] 
     FROM [dbo].[MetricBloodPreasure] AS [Extent1] 
     INNER JOIN [dbo].[User] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[Id] 
    ) AS [Project1] 
    ORDER BY [Project1].[LastName] ASC, [Project1].[FirstName] ASC 

Seconda con registrazione:

var result1 = (from u in context.User 
       orderby u.LastName, u.FirstName 
       join us in context.MetricBloodPreasure 
        on u.Id equals us.UserId into users 
       from s in users 
       select new 
       { 
        UserName = s.User.LastName + ", " + s.User.FirstName, 
        Date = s.DateOfValue, 
       }).ToList(); 

SQL generato:

SELECT 
    1 AS [C1], 
    CASE WHEN ([Extent1].[LastName] IS NULL) THEN N'' ELSE [Extent1].[LastName] END + N', ' + CASE WHEN ([Extent1].[FirstName] IS NULL) THEN N'' ELSE [Extent1].[FirstName] END AS [C2], 
    [Extent2].[DateOfValue] AS [DateOfValue] 
    FROM [dbo].[User] AS [Extent1] 
    INNER JOIN [dbo].[MetricBloodPreasure] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[UserId]) AND ([Extent2].[UserId] = [Extent1].[Id]) 

Prima di eseguire la prima query, chiamare var user = context.User.FirstOrDefault(); perché penso che la connessione aperta al database richieda del tempo.

Risultati: navigazione query di proprietà: 00: 00: 00,6719646 Registrazione query: 00: 00: 00,4941169

Guardando i risultati sembra che LINQ query che utilizzano unisce invece di proprietà di navigazione sono più veloci. È vero o sto facendo qualcosa di sbagliato?

+0

È inoltre necessario cancellare la cache dal database tra le query per ottenere risultati corretti quando si chiama ToList(). Separare la costruzione della query dalla materializzazione e confrontarli. –

+0

l'OrderBy non sembra essere preso in considerazione nella seconda query. Questa potrebbe essere la causa della differenza, puoi provare '... da s negli utenti, ordina u.LastName, u.FirstName ...' – jbl

risposta

2

Per ottenere una visione più chiara di ciò che sta facendo, è necessario ottenere l'SQL raw e verificare da soli il piano di esecuzione.

Per fare questo, è possibile utilizzare SQL Profiler per vedere quali query è in esecuzione, oppure è possibile accedere la query SQL in sé facendo qualcosa di simile prima di eseguire la query:

context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s); 

facendo anche un benchmark semplice come quello che hai fatto eseguendo ogni volta non sarà necessariamente affidabile. Ti consigliamo di eseguirlo più volte e fare la media delle cose. Dovresti anche eseguirli nell'ordine opposto per vedere se questo cambia anche le cose.

+0

Inoltre, l'inserimento di più dati nel database è una buona idea, questo dovrebbe evidenziare una differenza (se esiste) –

+0

entrambe le query restituite su 9000 righe ... e sì, uso il log ed eseguo le query con una nuova istanza del contesto del mio database. Unirsi è ancora più veloce. – puko

+0

Puoi pubblicare l'SQL che viene eseguito nella domanda originale? Inoltre, hai eseguito l'SQL nel SSMS e attivato il piano di esecuzione in modo che tu possa vedere dove sono le differenze? –