Sto sviluppando un sistema che periodicamente (4-5 volte al giorno) esegue un'istruzione select, che normalmente richiede meno di 10 secondi ma che richiede periodicamente fino a 40 minuti.Intermittente query lenta su SQL Server 2008
Il database è su Windows Server 2008 + SQL Server 2008 R2; entrambi a 64 bit.
Esiste un servizio sulla macchina che esegue il database che esegue il polling del database e genera valori per i record che lo richiedono. Questi record vengono quindi interrogati periodicamente utilizzando un join multi tabella selezionato da un servizio su una seconda macchina scritta in C++ (VS 2010) utilizzando la classe MFC CRecordset per estrarre i dati. Di seguito è riportato un esempio della query che causa il problema.
SELECT DISTINCT "JobKeysFrom"."Key" AS "KeyFrom","KeysFrom"."ID" AS "IDFrom",
"KeysFrom"."X" AS "XFrom","KeysFrom"."Y" AS "YFrom","JobKeysTo"."Key" AS "KeyTo",
"KeysTo"."ID" AS "IDTo","KeysTo"."X" AS "XTo","KeysTo"."Y" AS "YTo",
"Matrix"."TimeInSeconds","Matrix"."DistanceInMetres","Matrix"."Calculated"
FROM "JobKeys" AS "JobKeysFrom"
INNER JOIN "JobKeys" AS "JobKeysTo" ON
("JobKeysFrom"."Key"<>"JobKeysTo"."Key") AND
("JobKeysFrom"."JobID"=531) AND
("JobKeysTo"."JobID"=531)
INNER JOIN "Keys" AS "KeysFrom" ON
("JobKeysFrom"."Key"="KeysFrom"."Key") AND ("JobKeysFrom"."Status"=4)
INNER JOIN "Keys" AS "KeysTo" ON
("JobKeysTo"."Key"="KeysTo"."Key") AND ("JobKeysTo"."Status"=4)
INNER JOIN "Matrix" AS "Matrix" ON
("Matrix"."IDFrom"="KeysFrom"."ID") AND ("Matrix"."IDTo"="KeysTo"."ID")
ORDER BY "JobKeysFrom"."Key","JobKeysTo"."Key"
Ho provato quanto segue
- controllato gli indici e tutti sembrano corretti e sono attivi e vengono utilizzati in base alla query
- il consulente di design torna con nessun suggerimento
- Ho provato a deframmentare gli indici ei dati
- ha ricostruito il database da zero esportando i dati e reimportandoli in un nuovo database.
- ha eseguito il profiler su di esso e ha scoperto che quando va storto sembra fare molti milioni (fino a 100 milioni) di letture piuttosto che poche centinaia di migliaia.
- correva il database su un server diverso
Durante il tempo è in esecuzione della query, posso correre esattamente la stessa query nella finestra di gestione dello studio e sarà di nuovo a correre in 10 secondi. Il problema non sembra essere il blocco, il deadlock, la CPU, il disco o la memoria correlati come è stato fatto quando la macchina che esegue il database stava eseguendo solo questa query. Il server ha 4 processori e 16 GB di memoria per eseguirlo. Ho anche provato ad aggiornare i dischi a quelli molto più veloci e questo non ha avuto alcun effetto.
Mi sembra che sia quasi come se il database riceve la query, inizia a elaborarlo e quindi va a dormire per 40 minuti o esegue la query senza utilizzare gli indici.
Quando impiega molto tempo, alla fine termina e invia i risultati della query (normalmente circa 70-100000 record) all'applicazione chiamante.
Qualsiasi aiuto o suggerimento sarebbe ben accetto, molte grazie
Questa query viene eseguita come una stored procedure con parametri? –
È possibile evitare il SELECT DISTINCT? Questo può danneggiare le prestazioni in modo pesante. –
@Yves: sembra che sia abbastanza performante da eseguire adhoc e ritorna in 10 secondi. –