Esecuele Sin Fronteras

SQL Server, Reporting Services y Biztalk Server
  • Esecuele Sin Fronteras

    Uso de campos XML en SQL SERVER

    • 0 Comments

    INTRODUCCION.-

    Hemos observado en algunos casos en determinados proyectos que usan SQL SERVER se implementan campos de tipo TEXT para almacenar datos de XML.

    Desde la versión de SQL SERVER 2005 existe la posibilidad o bien de leer archivos de XML y poder manipularlos o almacenarlos como un campo de XML dentro de una tabla de SQL SERVER.

    Nuestro pequeño post girará en entorno al nuevo tipo de dato XML que nos permite realizar operaciones desde la lectura, indexación por path, valores y tags así como poder actualizar sólo la parte del XML sin tener que sustituir todo el contenido del campo, ahorrando muchas de las operativas de manipulación por parte de desarrollador.

    Con el fin de crear una pequeña guía de trabajo del uso de este nuevo tipo de datos, os mostraremos varios detalles del mismo.

    TABLA DE EJEMPLO.-

    Lo primero que vamos a realizar será crear una tabla que llamaremos EjemploXML que contendrá dos campos:

    • XML_ID de tipo integer y autoincremental que nos permitirá crear una clave única para el ejemplo.
    •  
    • XML_Data de tipo XML que nos permitirá almacenar los datos en XML.

    clip_image001[22]

     

    OPERACIONES.-

    Una vez ya tenemos la tabla vamos a realizar operaciones básicas como:

    Insertar varios registros pudiendo utilizar dos formas:

    • SQL Directa: Insert Into EjemploXML(XML_Data) Values('<cliente>Juan Perez</cliente>')

     

    • O más avanzada usando una variable de tipo XML:

    DECLARE @xml AS XML

    SET @xml = '<Clientes> <Cliente> <ClienteID>2005</ClienteID> <Nombre>25</Nombre> </Cliente> </Clientes>’

    INSERT INTO EjemploXML(XML_Data) Values (@xml)

    Una vez hemos insertado estos datos, podemos ya realizar nuestras propias sentencias de SQL. Por un lado:

     

    • SELECT * FROM EjemploXML , que nos mostraría línea a línea los registros y su contenido XML.

     

     

    • Si queremos filtrar por algún contenido del XML, basta con añadir una serie de operadores que nos permitirán filtrar cualquier de los datos disponibles:

    SELECT * FROM EjemplosXML where xml_data.exist('/Clientes/Cliente/ClienteID[text()=10]')=1

     

    Comentar dos casos en relación a las búsquedas:

     

    • Cuando existen muchos XML por procesar, podemos como cualquier base de datos crear índices, pero estos índices al ser campos del tipo XML, son “algo especiales en su construcción”, por ejemplo:

     

    • Lo primero crearemos un índice primario como cualquier otro que podamos crear: CREATE Primary XML INDEX xml_idx_1 ON EjemploXML(XML_Data) Con este índice indicaremos a SQL SERVER que este campo XML tiene un índice.

     

     

    CREATE XML INDEX xml_idx_1_a ON EjemploXML(XML_Data) USING XML INDEX xml_idx_1 FOR PATH

    CREATE XML INDEX xml_idx_1_v ON EjemploXML(XML_Data) USING XML INDEX xml_idx_1 FOR value

    CREATE XML INDEX xml_idx_1_p ON EjemploXML(XML_Data) USING XML INDEX xml_idx_1 FOR property

     

    Finalmente, nos queda la posibilidad de bien, borrar o actualizar los datos de un XML. Para ello tenemos los siguientes métodos explicados en la siguiente URL: http://msdn.microsoft.com/es-es/library/ms177454.aspx

    NOTAS GENERALES.-

     

    Comentar por último que los nuevos tipos de datos de XML no sólo pueden usarse como campos de tablas, sino, que tienen otras funcionalidades como:

     

    • Devoluciones de valores de funciones UDF
    • Parámetros de procedimientos almacenados y funciones
    • Tipos de variables
    •  

    A parte, otras de las ventajas de que disponemos, es que podemos aplicar un constraint para evitar que un XML no esté bien formado, es decir, validar esquemas de XML o bien podemos añadir el contenido directamente del XML a través del comando BULK INSERT

  • Esecuele Sin Fronteras

    SQLOS–Introducción scheduling

    • 0 Comments

    En este post vamos a introducir el manejo a bajo nivel que hace SQL de las tareas que le piden los usuarios, como algunos sabréis SQL tiene su proprio “sistema operativo” que se encarga del scheduling, memoria etcetera, este componente recibe el original nombre de SQLOS. En este post nos centraremos en la parte de scheduling, para apoyar las explicaciones vamos a usar las vistas dinámicas que proporciona SQL Server a partir de su versión 2005 (http://msdn.microsoft.com/en-us/library/ms188754.aspx).

    Nodes

    Los nodos pertenecen más a la parte de memoria, pero juegan un papel muy importante a la hora de crear otros los schedulers, SQLOS crea un nodo por cada nodo NUMA (http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access) que tenga la máquina más un nodo adicional para la conexión dedicada de administración (DAC), si nuestra máquina es UMA (http://en.wikipedia.org/wiki/Uniform_Memory_Access) se crearan dos nodos uno para uso normal y otro para el DAC.

    Para ver los nodos que ha creado nuestro SQLOS podemos recurrir a la vista: sys.dm_os_nodes (http://msdn.microsoft.com/en-us/library/bb510628(v=sql.100).aspx), en mi máquina podemos ver que solo crea dos nodos, uno para uso normal y otro para uso del DAC.

    image

    El id de los nodos es consecutivo excepto el DAC que para 32bits es 32 y para 64bits es 64. En el estado podemos ver como todos están ONLINE (normalmente deben estar así), luego su dirección de memoria del nodo que para tareas de depuración de SQLOS viene muy bien y la máscara de afinidad del nodo, en sistemas con un solo socket veremos que la afinidad es 255, en sistemas con varios sockets veremos que la afinidad se ajusta al numero de cores de cada socket.

    Para procesadores X64 indicar que todos los procesadores con controladora interna de memoria son procesadores NUMA esto incluye todos los procesadores AMD (Opteron, Athlon X64 y posteriores) y los procesadores de intel basados en Nehalem (http://en.wikipedia.org/wiki/Nehalem_(microarchitecture)) y posteriores (Sandy Bridge, Ivy Bridge…)

    La tecnología IA64 (Itanium) es NUMA.

    Schedulers

    Para estudiar los diferentes componentes vamos a ir de abajo a arriba, en la parte más baja entran los schedulers, este componente es el encargado de realizar el scheduling entre las diferentes tareas tanto de usuario como de sistema. SQL Server crea un scheduler de usuario por cada CPU lógica que tenga el sistema, y algunos más para tareas internas.

    Para ver los schedulers del sistema tenemos la vista dinámica sys.dm_os_schedulers (http://msdn.microsoft.com/en-us/library/ms177526.aspx). La salida de esta vista en mi máquina:

    image

    Como con los nodos tenemos la dirección de memoria del Scheduler así como a que nodo pertenece, mi máquina es un i7 (Nehalem) de un solo socket y cuatro cores, como tengo Hyper-Threading (HT) activado el número de cores lógicos es ocho, por tanto SQLOS crea ocho schedulers, uno por core lógico, para tareas de usuario (status = VISIBLE), adicionalmente crea 4 schedulers para tareas administrativas y  uno para el DAC. La columna is_idle nos indica si el scheduler está ejecutando algo [0] o está sin hacer nada [1], Failed_to_create_worker es una columna interesante ya que nos indica si el scheduler a fallado en crear un worker [1] en algun momento, si es así podemos encontrarnos ante problemas de presión de memoria, o un valor de worker threads (http://msdn.microsoft.com/en-us/library/ms187024.aspx) muy alto si hemos establecido esta opción a mano, no recomendable.

    Indicar que en máquinas dedicadas exclusivamente a SQL puede ser buena opción desactivar Hyper-Threading a nivel de BIOS esto provocará que el número de cores lógicos corresponda con el número de cores físico haciendo que SQL cree un scheduler por core físico, reduciendo posibles esperas causadas por Hyper-Threading. Para determinar el impacto en el rendimiento se recomienda probar una carga de uso normal en un entorno de preproducción tanto con HT activado como con HT desactivado.

    Workers

    Cada scheduler tiene un número n de workers, el número global de workers en toda la instancia no puede sobrepasar el valor ‘max worker threads’. Cuando llega un nuevo trabajo el scheduler busca un worker libre si no existe ninguno intenta crear uno nuevo y asignarle la tarea. Para poder ver los workers del sistema podemos usar la vista: sys.dm_os_workers (http://msdn.microsoft.com/en-us/library/ms178626.aspx)

    image

    Como siempre la primera columna (worker_address) es la dirección de memoria del objeto, is_preemtive lo veremos más adelante, exception_num es el último numero de error que se ha producido en ese worker, en la captura podemos ver un 1222 que significa lock timeout. en state podemos ver si el worker está corriendo o suspendido, en last_wait_type podemos ver por que estaba esperando en la última espera que hizo el thread, posteriormente tenemos las direcciones de memoria de: task que está ejecutando el worker, el thread de windows usado para ejecutar la tarea y el scheduler al cual pertenece este thread.

    Task

    Esto representa una tarea, o subtarea de un usuario, cuando el engine decide paralelizar una query creará subtasks que se asignaran a workers libres para completar la query original. La vista que nos proporciona esta información es: sys.dm_os_tasks (http://msdn.microsoft.com/en-us/library/ms174963.aspx). En mi máquina

    image

    Aquí podemos ver la dirección de la tarea, el estado en el que está la tarea, el scheduler en el que está ejecutando la tarea, el número de sesión de usuario que ha lanzado la tarea y la dirección del worker que está ejecutando la tarea.

    Mezclandolo todo

    Para empezar vamos a recordar las relaciones entre elementos.

    SQLOS tiene tantos nodos como nodos NUMA tenga la máquina,

    SQLOS tiene tantos schedulers como cores lógicos reporte windows.

    Cada scheduler tiene n workers y un worker solo puede pertenecer a un scheduler.

    Cada worker tiene uno y solo un thread.

    Cada worker tiene una y solo una tarea. Una vez completada la tarea el worker puede tener una tarea nueva.

    Una tarea solo puede pertenecer a un worker.

    Llega una nueva tarea, ¿ahora que hago?

    Cuando llega una nueva tarea se le asigna un scheduler, este scheduler busca entre sus workers si hay algun que no esté haciendo nada, si es así se asigna la tarea al worker y se coloca en la lista de workers que pueden ser ejecutado. Si no hay ningun worker libre se intenta crear uno nuevo. Cuando al worker le toque ejecutar se le dara el procesador y es el worker el que debe decidir cuanto tiempo permanece en el. ¡Multitarea colaborativa!

    Multitarea colaborativa en SQLOS

    Como hemos visto es decisión del worker cuando devuelve el control al scheduler para que pueda ejecutar otro worker. Todos las tareas internas de SQL Server se controlan para no estar mucho tiempo ocupando el scheduler y que la ejecución sea fluida, esto se hace por rendimiento ya que simplifica enormemente el scheduler.

    Bien, pero y si una tarea tarda mucho

    Para estos casos existe una monitorización de los schedulers, si un scheduler no ha hecho un cambio de contexto en cierto tiempo se genera un volcado de memoria del scheduler afectado, elimina la task y marca el worker como libre.

    Seguramente muchos de vosotros os habréis encontrado con un volcado cuya descripción es “Non-Yielding Scheduler”, este tipo de volcados significa que un worker no ha retornado el control al scheduler en un tiempo adecuado, por tanto la tarea es terminada para no afectar a las restantes.

    Que pasa cuando es necesario hacer una llamada a Windows.

    Como muchos sabréis la multitarea de Windows es preemtiva, esto quiere decir que es el sistema operativo el que quita la ejecución a los procesos y se los asigna a otros procesos sin que el proceso afectado se entere de nada. Que pasa si tengo que hacer una llamada a Windows, ODBC, … cuya multitarea es preemtiva. En ese caso se marca el flag is_preemtive en el worker para evitar que el monitor de schedulers genere un volcado y mate el proceso en caso de que este tarde mucho en responder, como puede ser un acceso a disco, registro....

    Pablo Gavela López – Microsoft Customer Support Services

Page 1 of 1 (2 items)