2015-08-06 16 views
9

Ho un problema di prestazioni che abbiamo fatto un sacco di analisi e sono bloccati. Spero che qualcuno di voi abbia già visto questo.EF6 SQLQuery molto lento ma il database è molto veloce

Sto chiamando DbContext.Database.SqlQuery la parte del database richiede 3 ms ma l'esecuzione completa richiede 9 secondi.

Abbiamo utilizzato EF Profiler per scoprirlo e abbiamo anche eseguito SQL direttamente in SQL Server Management Studio ed è istantaneo.

Abbiamo anche usato un'occhiata e non siamo riusciti a vedere abbastanza in profondità nel processo.

Il tipo di risultato non è un'entità del modello e pertanto siamo certi che il tracciamento non sia coinvolto.

Sappiamo anche che questa non è la prima query eseguita sul contesto, pertanto non stiamo pagando il costo di avvio EF su questa query.

Abbiamo provato il .net profiler e abbiamo avuto così tanti problemi che abbiamo deciso di chiedere.

Qualche consiglio su come scavare e scoprirlo?

EDIT: Il set di risultati per questa ricerca è 1 riga con 4 colonne (decimale)

La linea di codice è solo:

var list=contextInstance.Database.SqlQuery<nonEntityType>(sqstring).ToList(); 

SQL sé non è una stringa molto lunga. Utilizzeremo un profiler più dettagliato per scoprire in che punto del processo si blocca.

+1

L'unica cosa che posso immaginare è che un'enorme quantità di dati va sul filo, e ci vuole tempo per creare la lista/matrice risultante/qualunque sia l'elaborazione del risultato. Questo non viene misurato nel tempo di esecuzione SQL –

+0

Scommetto su indici. –

+1

@DavidLeitner Non penso che sia un problema di indice * perché la query stessa viene eseguita molto rapidamente in SQL Server. Quindi è qualcosa prima che la query venga inserita nel db o in uscita. Nessuna delle query LINQ sta mostrando questo tipo di differenza. L'intervallo tra il tempo di esecuzione db e il tempo di esecuzione completo della query EF è minimo. * Voglio sempre dire anche degli indici! :) Non so mai quale sia corretto! :) –

risposta

1

Abbiamo utilizzato EF profiler per scoprirlo e abbiamo anche eseguito lo SQL direttamente nello studio di gestione server SQL ed è istantaneo.

Questo non prova nulla. La query potrebbe essere veloce, ma i dati potrebbero generare 100 MB di dati che verranno quindi trasportati al client e materializzati in oggetti. Questo potrebbe richiedere più tempo di quanto pensi.

La query in SSMS potrebbe tornare istantanea perché mostra solo una parte dei dati. Non hai detto quali erano i dati.

Utilizzare un profiler .NET reale, come dotTrace o Ants. In questo modo puoi vedere dove il tempo si perde esattamente sulla linea. EF Prof (o il mio ORM Profiler: http://www.ormprofiler.com) ti dirà quale parte del percorso totale (ORM-> DB-> ORM) prende l'ora. Perfino EF prof;)

+0

OP seguito dal fatto che il set di risultati è 1 riga con 4 colonne decimali scalari. è minuscolo. Ha anche scritto: "Sto chiamando DbContext.Database.SqlQuery la porzione del database impiega 3ms ma l'esecuzione completa impiega 9 secondi.Abbiamo usato EF Profiler per scoprire questo" EF Prof è quello che ha dimostrato che l'RT completo è di 9 secondi ma la parte db era solo pochi ms.Abbiamo passato molto tempo a combattere il profiler di VS (che uso molto io stesso) per cercare di vedere più a fondo dove può essere il codice del collo di bottiglia. Chiesto qui nella speranza di evitare ulteriori sprechi di tempo. ORMP mostra più dettagli rispetto alla chiamata di contesto e alla query db? –

+2

Verrà visualizzato da con Apri per con chiudere quale parte ha richiesto in quale momento e le pile di chiamate. Se lo stato di connessione aperta è durato 9 secondi, EF è in errore, ma EF prof lo direbbe anche a te. vs 'profiler, lascia perdere. Usa dotTrace o formiche, ti dirà quale linea ha preso a che ora. Ti ci vorranno 10 secondi. –

1

Se il cliente per qualche motivo non può usare un profiler come suggerito da Frans, dovrai giocare al gioco di ipotesi ed escludere le possibilità.

Prima di tutto penso che manchi un'informazione critica. Ci vogliono sempre circa 9 secondi o varia?

Primo passo:

decidere se il ritardo è prima o dopo l'interrogazione colpisce il database. Dovrebbe essere possibile fare entrambi con EF profiler e guardare i timestamp in Sql profiler.

In entrambi i casi avrete un po 'limitato le possibilità.

Secondo passo:

Escludere il più possibile

  • indici (No, la query è veloce)
  • Restituzione di troppi dati (No, secondo le informazioni che avete)
  • Compilazione query lenta (No, viene utilizzata query sql raw)
  • Trasferimento dati lento (No, le altre query funzionano correttamente)
  • Inizializzazione Lenta DbContext (No, hai detto che non è la prima query)
  • Serrature di riga o tabella (Non probabile, che probabilmente si presenterebbe come una query di lunga esecuzione nel profiler)
  • materializzazione lenta (No, a pochi campi a meno che non vi sia un grave bordo caso bug)

Terzo passo:

cosa rimane? Dipende dalla risposta al n.1 e anche se è sempre 9 secondi.

I miei sospetti principali sono alcuni problemi di connessione perché un'altra chiamata sta bloccando, quindi deve attendere una connessione o qualche cache di secondo livello o qualcosa che non funzioni bene con questa query.

Per escludere ulteriori alternative, proverei a eseguire la stessa query utilizzando semplicemente ADO.NET vecchio. Se il problema persiste, sai che non è un problema di EF e molto probabilmente un problema di connessione. Se va via potrebbe comunque essere entrambi problemi.

Non tanto una risposta quanto qualche sproloquio, ma si spera che qualcosa a cui non avevate già pensato.