Tenemos una base de datos para un producto que es pesado para escribir. Acabamos de comprar una nueva máquina servidor con un SSD para ayudar. Para nuestra sorpresa, las inserciones no fueron más rápidas que en nuestra vieja máquina con un almacenamiento mucho más lento. Durante la evaluación comparativa, notamos que la tasa de E / S exhibida por el proceso de SQL Server era muy baja.
Por ejemplo, ejecuté el script que se encuentra en esta página , excepto que agregué un BEGIN TRAN y COMMIT alrededor del ciclo. En el mejor de los casos, pude ver que el uso del disco alcanza los 7Mb / s, mientras que la CPU apenas alcanzó el 5%. El servidor tiene 64 Gb instalados y está utilizando 10. El tiempo total de ejecución fue de 2 minutos y 15 segundos para la primera llamada, hasta alrededor de 1 minuto para las siguientes. La base de datos está en recuperación simple y estaba inactiva durante la prueba. Dejé caer la mesa entre cada llamada.
¿Por qué un script tan simple es tan lento? El hardware apenas se está utilizando en absoluto. Tanto las herramientas dedicadas de evaluación comparativa de disco como SQLIO indican que el SSD funciona correctamente con velocidades superiores a 500 Mb / s tanto para lectura como para escritura. Entiendo que las escrituras aleatorias son más lentas que las escrituras secuenciales, pero esperaría que una inserción simple como esta, en una tabla sin indexación agrupada, sea mucho más rápida.
En última instancia, nuestro escenario es mucho más complejo, pero siento que primero necesito entender un caso simple. En pocas palabras, nuestra aplicación elimina datos antiguos, luego usa SqlBulkCopy para copiar datos nuevos en tablas de preparación, realiza algunos filtros y finalmente usa MERGE y / o INSERT INTO dependiendo de los casos para copiar los datos en las tablas finales.
-> EDITAR 1: Seguí el procedimiento vinculado por Martin Smith, y obtuve el siguiente resultado:
[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
Encuentro extraño que NETWORK_IO toma la mayor parte del tiempo, considerando que no hay resultados para mostrar y que no hay datos para transferir a ningún otro lugar que no sea a los archivos SQL. ¿El tipo NETWORK_IO incluye todas las IO?
-> EDIT 2: creé un disco RAM de 20 Gb y monté una base de datos desde allí. El mejor tiempo que tuve en el SSD fue de 48 segundos, con el disco RAM bajó a 37 segundos. NETWORK_IO sigue siendo la mayor espera. La velocidad máxima de escritura en el disco RAM era de aproximadamente 250 Mb / s, mientras que es capaz de hacer varios gigabytes por segundo. Todavía no estaba usando mucha CPU, entonces, ¿qué está retrasando SQL?
NETWORK_IO
podría ser del 3 millones "1 fila (s) afectadas" mensajes que están siendo enviados de vuelta. ¿Intentaste agregar SET NOCOUNT ON
al script?
EE_WaitStats*.xel
que los viejos contaminen sus resultados.
SET NOCOUNT ON
a eso.