En nuestro anterior artículo vimos la necesidad de trabajar directamente con los documentos XML en vez de con los documentos o datos originales, para hacer la conversión una sola vez. Pero realmente la forma en que trabaja SQL Server con los documentos XML hace que esto sea bastante más necesario. Veamos por qué.

Tablas temporales

Vamos a seguir la primera recomendación a ver qué pasa. Para ello vamos a medir exclusivamente cuánto tardamos en convertir las zonas de memoria donde se guardan las estructuras de los planes cacheados, en documentos XML organizados. Decimos organizados porque SQL Server no conserva el formato original del documento, sino que lo guarda en un formato optimizado para las búsquedas y las consultas. Para ver todo esto, usaremos la forma más simple de nuestra consulta anterior.

Lo primero es generar la tabla temporal donde vamos a guardar los subplanes. Como un plan XML puede contener varios planes internamente –por ejemplo, un lote con varias consultas o un procedimiento almacenado–, no podemos usar el identificador del plan como clave primaria. Es decir, aunque dicho identificador no se repita en sys.dm_exec_cached_plans, sí se va a repetir muy fácilmente en la tabla temporal al extraer de cada documento los varios planes que pueda contener. En resumen, en esta tabla no podríamos crear índices XML. Luego lo veremos.

Llenado de la tabla temporal

La consulta que llena la tabla temporal anterior es la siguiente y vamos a ver que en realidad mide varias cosas:

Tarda mucho, pero al menos no desborda la tempdb y eventualmente termina. Hora y media para traer los planes en formato XML. ¿O hace más cosas? Veamos el nuevo plan:

Desde luego es bastante más sencillo, pero es que el trabajo que hace SQL Server con estos documentos tan grandes es bastante superior a lo que pensamos. Y antes de que opinemos que hay bastante ineficiencia, escuchemos a Michael Rys, para que veamos que la implementación es bastante buena y además es que trabajar con documentos tan grandes es costoso en sí mismo.

Table Spool

Vamos a analizar la primera parte del plan más en detalle:

La primera diferencia que vemos es que de la TVF interna que se llama para obtener el identificador del plan, dicho identificador se convierte en un varbinary(64) porque luego se va a guardar en la tabla temporal. Sin embargo, si vemos el operador FNGETQUERYPLAN, vemos que no le pasa el valor convertido sino directamente SYSDMEXECCACHEDPLANS.[plan_handle]. No vamos a entrar en ello, no afecta a lo que estamos estudiando.
A continuación vemos que en esta ocasión sí que hay un operador Table Spool que guarda los datos devueltos. Por lo tanto, ya hemos conseguido una ventaja muy importante frente al plan anterior: cacheamos los planes.

Nodos con planes

Seguimos teniendo los cuatro operadores «XML Reader with XPath filter» correspondientes a la función nodes que se concatenan –operador del mismo nombre– igual que en el plan anterior, pero en esta ocasión actuando sobre valores cacheados.

Pero fijémonos en lo que devuelve el operador Concatenation:

Vemos que no devuelve el nodo, es decir, el XML correspondiente al nodo, sino un identificador. Por lo tanto, siempre trabajamos con el documento completo y la función nodes devuelve un puntero a la posición del nodo dentro del documento. Ojo con la documentación por dos razones: Una es que no siempre especifica que es un puntero y la otra que en realidad es un identificador dentro de la tabla relacional que se ha construido internamente con los nodos del documento XML.

Ahora entendemos qué pasó con la tempdb en el primer intento: como no se cachearon las «tablas internas XML», se iban construyendo una tras otra según se relacionaban en el plan por cada iteración: armamos un desastre.

Número de nodos

Vamos a analizar la última parte del plan y vamos a destacar la enorme complejidad que tenían los documentos, porque al final hubo que analizar 31.360 planes:

Pero se generaron casi 40 millones de nodos:

Pues sí, aún con la optimación estamos trabajando con bastantes millones de nodos, imaginémonos lo que fue multiplicar esto por cada iteración. ¡Tenemos que tener mucho cuidado con los documentos XML grandes!

Búsqueda de nodos principales

Por último, en este artículo vamos a ver la diferencia que hay de trabajar con documentos grandes a trabajar con los nodos ya procesados. Recordemos que estamos trabajando sólo con algo más de treinta y un mil nodos:

Como podemos ver, la diferencia es dramática, pasa de una hora y media el procesar los documentos grandes a menos de un minuto el procesar nodos pequeños. Podemos ver por qué es tan importante el tamaño de cada documento, porque en realidad, aunque en la tabla relacional un documento esté en una fila, en la tabla interna que se crea para trabajar con dicho documento puede haber hasta millones de registros.

CONCLUSIÓN

Cuando trabajamos con documentos XML grandes suele ser beneficioso el emplear varios pasos para obligar a SQL Server a trabajar con datos cacheados cuando el plan no incluya dicho caché.
Pero en el último punto hemos hecho una trampa, sólo pedimos un dato. En un próximo artículo veremos qué trascendencia tiene esto.

Más Información

Desde Danysoft y si rellenas este formulario, te ayudaremos a facilitarte la información que necesitas.

Este formulario de contacto está desactivado porque rechazaste aceptar el servicio de Google reCaptcha, que es necesario para validar los mensajes enviados a través del formulario.
0 comentarios

Dejar un comentario

¿Quieres unirte a la conversación?
¡Siéntete libre de contribuir!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *