2011-05-25 13 views
6

La nostra applicazione emette una query SQL generata da NHibernate. Al runtime dell'applicazione, la query impiega circa 12 secondi per essere eseguita su un database SQL Server. SQL Profiler mostra oltre 500.000 letture.La stessa query SQL è più lenta dall'applicazione NHibernate rispetto a SQL Studio?

Tuttavia, se acquisisco il testo della query esatta utilizzando SQL Profiler e lo eseguo nuovamente da SQL Studio, sono necessari 5 secondi e vengono visualizzate meno di 4.600 letture.

La query utilizza un paio di parametri i cui valori sono forniti alla fine del testo SQL, e vorrei leggere un po 'di snifing dei parametri e piani di query inefficienti, ma avevo pensato che fosse relativo alle stored procedure. Forse NHibernate tiene aperto il set di risultati mentre istanzia le sue entità, il che potrebbe spiegare la durata più lunga, ma cosa potrebbe spiegare le ulteriori 494.000 "letture" per la stessa query eseguita da NHibernate? (Nessuna query aggiuntiva viene visualizzata nella traccia di SQL Profiler.)

La query viene specificata come una query LINQ utilizzando la funzione LINQ di NHibernate 3.1. Non ho incluso la query stessa perché sembra una domanda di base della filosofia: cosa potrebbe spiegare una differenza così drammatica?

Nel caso sia pertinente, nei risultati esiste anche una colonna varbinary (max), ma nella nostra situazione contiene sempre null.

Qualsiasi intuizione è molto apprezzata!

+3

Parametro sniffing vale anche per AdHoc query parametrizzate non solo le stored procedure. I piani per questi vengono compilati in base al primo set di parametri e riutilizzati per le successive chiamate con valori di parametro eventualmente diversi. –

+1

Hai mai capito il problema? Sono imbattuto nella stessa cosa, e tutti i miei parametri sono int in modo da non vedere come questo potrebbe essere un problema. – Justin

risposta

2

Leggere: http://www.sommarskog.se/query-plan-mysteries.html

stesse regole si applicano per procs e sp_executesql. Un'enorme ragione per cui piani scadenti possono passare in un parametro nvarchar per un campo varchar, causa scansioni dell'indice anziché ricerche.

Dubito molto che l'uscita stia influenzando il perf qui, è probabile che sia un problema con uno dei parametri inviati, o selettività delle tabelle sottostanti.

Quando si verifica l'output dal profiler, assicurarsi di includere sp_executesql e assicurarsi che le impostazioni corrispondano (roba come SET ARITHABORT), altrimenti si genererà un nuovo piano.

si può sempre scavare il piano scadente dalla cache di esecuzione tramite sys.dm_exec_query_stats

+0

si applica la stessa cosa per INT vs BIGINT? – Phill

+0

@Phill non sembra che SQL sia felice di utilizzare l'indice corretto in quel caso –

+0

Ok, abbiamo un database legacy in cui lo sviluppatore originale stava pensando in grande. (il database ha 10 anni) tutte le nuove tabelle sono INT ma con riferimento a chiave esterna a BIGINT. Mi hai fatto preoccupare per un momento che potrebbe causare problemi di prestazioni! – Phill

Problemi correlati