Estoy trabajando con el XML de observación actual de NOAA (ejemplo: Washington DC) y estoy triturando los archivos de las 4000+ estaciones en una tabla de SQL Server 2008 R2. Después de probar muchos enfoques diferentes, tengo uno con el que estoy avanzando.SQL Server XML shredding performance
Esta pregunta es sobre el rendimiento entre los diferentes métodos y lo más importante es por qué es tan drástico.
primer intento
Trabajando en C# Me analizado sintácticamente todos los archivos con LINQ to XML y escribió los registros resultantes de la base de datos con LINQ a SQL. El código para esto es predecible, así que no te aburriré con eso.
Reescribir con linq a Entity Framework no ayudó.
Esto dio como resultado que la aplicación tardara más de una hora en ejecutarse y solo había procesado unos 1600 archivos. La lentitud es el resultado tanto de Linq a SQL como de Linq a entidades que ejecutan una inserción y seleccionan para cada registro.
segundo intento
Todavía trabajando en C# Me trataron de acelerarlo mediante el uso de los métodos de inserción a granel disponible en línea (ejemplo: Speeding up inserts using Linq-to-SQL - Part 1).
Todavía lento, aunque notoriamente más rápido que el primer intento.
En este punto pasé a utilizar un procedimiento almacenado para manejar la trituración XML e insertar con el código C# concatenando los archivos en una cadena XML y agregando una etiqueta contenedora.
tercer intento
El uso de XML Query de SQL Server similar a este (@xml es el archivo XML) [de la memoria]:
select credit = T.observation.value('credit[1]', 'varchar(256)')
,... -- the rest of the elements possible in the file.
from @xml.nodes('wrapper') W(station)
cross apply W.station.nodes('current_observation') T(observation)
que se deja correr durante 15 minutos y se cancela con 250 o más registros procesados.
cuarto intento
me cambió la consulta para utilizar OpenXML:
declare $idoc int
exec sp_xml_preparedocument @idoc output, @xml
select Credit
,... -- the rest of the elements
from openxml(@idoc, '/wrapper/current_observations', 2)
with (
Credit varchar(256) 'credit'
,...) -- the rest of the elements
exec sp_xml_removedocument @idoc
Este procesados todos los registros de 4000 en 10 segundos! Muy aceptable.
Mientras esperaba algunas diferencias entre los métodos, no esperaba que la diferencia fuera tan dramática.
Así que mi pregunta es, simplemente,
'¿Por qué hay una diferencia tan drástica en el rendimiento entre los diferentes métodos?
Estoy muy contento de que se muestre que estaba usando las 3 primeras incorrectas.
sí, estoy sacando el nodo current_observation de cada archivo y concatenándolos con un elemento alrededor del lote de ellos. –
Pensé que había intentado hacer referencia a la etiqueta current_observation sin aplicar la cruz, pero aparentemente no. Vuelvo a ejecutar la prueba con los cambios sugeridos y, como esperabas, los tiempos son mucho más rápidos. Para procesar los más de 4000 elementos current_observation tomó 43 segundos. Si bien tomó 4 veces más tiempo, está en el mismo vecindario y explica por qué las diferencias fueron tan drásticas antes. –
@DavidCulp: genial, gracias por los comentarios! Es bueno saber –