Nous avons une base de données pour un produit lourd en écriture. Nous venons d'acheter une nouvelle machine serveur avec un SSD pour vous aider. À notre grande surprise, les insertions n'étaient pas plus rapides que sur notre ancienne machine avec un stockage beaucoup plus lent. Lors de l'analyse comparative, nous avons remarqué que le taux d'E / S présenté par le processus SQL Server était très faible.
Par exemple, j'ai exécuté le script trouvé sur cette page , sauf que j'ai ajouté un BEGIN TRAN et un COMMIT autour de la boucle. Au mieux, je pouvais voir l'utilisation du disque atteindre 7 Mo / s, tandis que le processeur atteignait à peine 5%. Le serveur a 64 Go installés et en utilise 10. La durée totale d'exécution était de 2 minutes 15 secondes pour le premier appel à environ 1 minute pour les appels suivants. La base de données est en récupération simple et était inactive pendant le test. J'ai laissé tomber la table entre chaque appel.
Pourquoi un script aussi simple est-il si lent? Le matériel est à peine utilisé du tout. Les deux outils dédiés d'analyse comparative des disques et SQLIO indiquent que le SSD fonctionne correctement avec des vitesses allant jusqu'à 500 Mo / s pour la lecture et l'écriture. Je comprends que les écritures aléatoires sont plus lentes que les écritures séquentielles, mais je m'attendrais à ce qu'une simple insertion comme celle-ci, dans une table sans indexation en cluster, soit beaucoup plus rapide.
En fin de compte, notre scénario est beaucoup plus complexe, mais je pense que je dois d'abord comprendre un cas simple. En résumé, notre application supprime les anciennes données, puis utilise SqlBulkCopy pour copier les nouvelles données dans les tables de transfert, effectue un filtrage et enfin utilise MERGE et / ou INSERT INTO selon les cas pour copier les données dans les tables finales.
-> EDIT 1: J'ai suivi la procédure liée par Martin Smith, et j'ai obtenu le résultat suivant:
[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
Je trouve cela bizarre NETWORK_IO prend la plupart du temps, étant donné qu'il n'y a aucun résultat à afficher et aucune donnée à transférer ailleurs que dans les fichiers SQL. Le type NETWORK_IO inclut-il tous les E / S?
-> EDIT 2: J'ai créé un disque RAM de 20 Go et monté une base de données à partir de là. Le meilleur temps que j'ai eu sur le SSD est de 48 secondes, avec le disque RAM, il est tombé à 37 secondes. NETWORK_IO est toujours la plus grande attente. La vitesse d'écriture maximale sur le disque RAM était d'environ 250 Mo / s alors qu'il est capable de faire plusieurs gigaoctets par seconde. Il n'utilisait toujours pas beaucoup de CPU, alors qu'est-ce qui retarde SQL?
NETWORK_IO
pourrait provenir des 3 millions de messages "1 ligne (s) affectée (s)" renvoyés. Avez-vous essayé d'ajouter SET NOCOUNT ON
au script?
EE_WaitStats*.xel
afin que les anciens contaminent vos résultats.
SET NOCOUNT ON
aussi.