Abbiamo un database per un prodotto che è pesante per la scrittura. Abbiamo appena acquistato un nuovo server con un SSD per aiutare. Con nostra sorpresa, gli inserimenti non sono stati più veloci rispetto alla nostra vecchia macchina con una memoria molto più lenta. Durante il benchmarking abbiamo notato che la velocità di I / O mostrata dal processo di SQL Server era molto bassa.
Ad esempio, ho eseguito lo script trovato in questa pagina , tranne per il fatto che ho aggiunto BEGIN TRAN e COMMIT attorno al loop. Nel migliore dei casi ho visto l'utilizzo del disco raggiungere i 7 Mb / s, mentre la CPU ha toccato appena il 5%. Il server ha 64 GB installati e sta usando 10. Il tempo di esecuzione totale è stato di 2 minuti e 15 secondi per la prima chiamata fino a circa 1 minuto per le chiamate successive. Il database è in fase di recupero semplice ed era inattivo durante il test. Ho lasciato cadere il tavolo tra ogni chiamata.
Perché una sceneggiatura così semplice è così lenta? L'hardware non viene quasi mai usato. Entrambi gli strumenti dedicati di benchmarking del disco e SQLIO indicano che l'SSD funziona correttamente con velocità superiori a 500 Mb / s sia in lettura che in scrittura. Capisco che le scritture casuali sono più lente delle scritture sequenziali, ma mi aspetterei che un semplice inserimento come questo, su una tabella senza indicizzazione in cluster, sia molto più veloce.
Alla fine il nostro scenario è molto più complesso, ma sento che devo prima capire un caso semplice. In breve, la nostra applicazione elimina i vecchi dati, quindi utilizza SqlBulkCopy per copiare nuovi dati nelle tabelle di gestione temporanea, esegue alcuni filtri e infine utilizza MERGE e / o INSERT INTO a seconda dei casi per copiare i dati nelle tabelle finali.
-> EDIT 1: ho seguito la procedura collegata da Martin Smith e ho ottenuto il seguente risultato:
[Wait Type] [Wait Count] [Total Wait (ms)] [T. Resource Wait (ms)] [T. Signal Wait (ms)]
NETWORK_IO 5008 46735 46587 148
LOGBUFFER 901 5994 5977 17
PAGELATCH_UP 40 866 865 1
SOS_SCHEDULER_YIELD 53279 219 121 98
WRITELOG 5 145 145 0
PAGEIOLATCH_UP 4 58 58 0
LATCH_SH 5 0 0 0
Trovo strano che NETWORK_IO richieda la maggior parte del tempo, considerando che non ci sono risultati da visualizzare e nessun dato da trasferire altrove che nei file SQL. Il tipo NETWORK_IO include tutti gli IO?
-> EDIT 2: ho creato un disco RAM da 20 Gb e da lì ho montato un database. Il miglior tempo che ho avuto sull'SSD è di 48 secondi, con il disco RAM che è sceso a 37 secondi. NETWORK_IO è ancora l'attesa più grande. La massima velocità di scrittura sul disco RAM era di circa 250 Mb / s mentre è in grado di eseguire più gigabyte al secondo. Non utilizzava ancora molta CPU, quindi cosa sta trattenendo SQL?
NETWORK_IO
potrebbe essere dal "1 row (s) affected" 3 milioni di messaggi inviati indietro. Hai provato ad aggiungere SET NOCOUNT ON
allo script?
EE_WaitStats*.xel
modo che quelli vecchi contaminino i tuoi risultati.
SET NOCOUNT ON
a questo.