Breaking

Post Top Ad

Your Ad Spot

domingo, 15 de diciembre de 2019

Consultar problemas de rendimiento en el tipo de datos VARCHAR utilizando un prefijo N

En este artículo, analizaremos el tipo de datos VARCHAR y los problemas de rendimiento de consultas asociados con la utilización del tipo de datos VARCHAR de nivel inferior. CHAR, VARCHAR y NVARCHAR son tipos de datos que admiten el almacenamiento de información en formato de texto en una base de datos de SQL Server. Estos tipos de datos permiten una amplia variedad de juegos de caracteres en el campo o columna definidos en la tabla de la base de datos.

La idea fundamental de NVARCHAR

NCHAR, NVARCHAR o NTEXT son similares a CHAR, VARCHAR OR TEXT, donde el prefijo N representa el conjunto de caracteres del idioma internacional. Los tipos de datos con el prefijo N indican que la cadena resultante podría estar compuesta por un conjunto de caracteres Unicode con longitud variable donde cada carácter ocupa 2 bytes. Sin el prefijo N, la cadena podría convertirse al juego de caracteres predeterminado de la base de datos, pero podría dar lugar a que ciertos caracteres especiales no se reconozcan como parte del Conjunto de caracteres de idioma internacional.
Las plataformas de desarrollo actuales o sus sistemas operativos admiten el juego de caracteres Unicode. Por lo tanto, en SQL Server, debe utilizar NVARCHAR en lugar de VARCHAR. Si utiliza VARCHAR cuando está presente la compatibilidad con Unicode, surgirá una inconsistencia de codificación al comunicarse con la base de datos. Esta inconsistencia causa problemas de rendimiento de consultas que eventualmente generan errores como bloqueo o un punto muerto en SQL Server.
¿Cómo puede recuperarse de este problema de rendimiento de la consulta? Los índices pueden fallar cuando se ha utilizado un tipo de datos incorrecto dentro de una columna. En SQL Server, si una columna VARCHAR indexada se presenta con una cadena Unicode N, SQL Server no podrá utilizar el índice. Un problema de rendimiento de consulta similar ocurre cuando una columna indexada que contiene datos INTEGER se presenta con datos de tipo VARCHAR. Hablaremos de más ejemplos a continuación.
Imagínese, que un SalesOrderHeader tabla tiene un ACCOUNTNUMBER columna con tipo de datos VARCHAR y el número total de filas es 31.465. ¿Qué ocurrirá si usamos el prefijo N antes de una cadena en una condición WHERE? Aquí, investigaremos un par de parámetros de rendimiento de la consulta sobre la ejecución de la consulta, por ejemplo, lecturas lógicas, utilización del índice, tiempo de ejecución, etc.

Columna VARCHAR con prefijo N ”

Tabla 'SalesOrderHeader'. Recuento de escaneo 1, lecturas lógicas 114, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas de lectura anticipada lob 0.
Tiempos de ejecución del servidor SQL: Tiempo de
   CPU = 16 ms, tiempo transcurrido = 16 Sra.
Los resultados de la consulta muestran que el recuento de lecturas lógicas es 114 y el recuento de escaneo es 1 para la declaración anterior. Tenemos un índice en la columna donde aplicamos un filtro, por lo que podemos verificar la lectura del uso del índice como se muestra a continuación:
Aquí, se escanea el índice y se escanea la tabla completa para obtener la fila individual de la tabla. Podemos verificar los parámetros Número real de filas (1) y Número de filas leídas (31465) en el plan de ejecución. Podemos ver que tenemos un índice en la columna con la cláusula where, pero ese índice no se está utilizando. ¿Cuál es la razón para esto?
Un parámetro más (CONVERT_IMPLICIT) está visible en el plan de ejecución. CONVERT_IMPLICIT es una función que convierte una columna al tipo de datos referenciado en la función. De esta manera, en Predicate, podemos ver que la columna se convierte a NVARCHAR antes de compararla con el valor de entrada. Además, esto explica que el índice no se usa para esta consulta porque el índice no se buscará cuando una columna se use con cualquier función en la cláusula Where.

Columna VARCHAR sin prefijo N ”

Tiempo de análisis y compilación de SQL Server: tiempo de CPU = 12 ms, tiempo transcurrido = 12 ms. (1 fila afectada) Tabla 'SalesOrderHeader'. Cuenta de escaneo 1, lecturas lógicas 5, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas de lob 0, lecturas de lectura anticipada lob 0. Tiempos de ejecución del servidor SQL: Tiempo de CPU = 0 ms, tiempo transcurrido = 0 Sra.
En esta consulta, la única diferencia con la anterior es que hemos eliminado N de la cláusula Where, y el recuento de lectura es solo 5. En el plan de ejecución que se muestra a continuación, podemos ver que el índice sobre la columna está recibiendo una búsqueda . El número real de filas, el número estimado de filas, el número estimado de filas a leer y el número de filas leídas es 1 son visibles en el plan de ejecución. Por lo tanto, tiene sentido no utilizar N con el tipo de datos VARCHAR:
El conjunto de resultados y las aclaraciones anteriores son solo para declaraciones SELECT;

Sesión 1

Aquí, estamos comenzando una transacción y eliminando una fila en la tabla SalesOrderHeader con un filtro en la columna AccountNumber. Como se muestra en la declaración anterior, la consulta SELECT está escaneando la tabla completa cuando usamos el prefijo N con la columna de tipo VARCHAR:
No confirmamos esta transacción para verificar algunos problemas de rendimiento de consultas.

Sesión: 2

Aquí, estamos comenzando otra transacción en SQL Server y eliminando una fila que no sea la fila de la sesión uno. En el momento en que comenzamos la ejecución de una declaración, la ejecución no se está terminando:
Monitor de consulta
Vamos a monitorear las estadísticas de la sesión SQL con la ayuda de DMV:
Podemos ver que la sesión dos existe con session_id: 68 en SQL Server y se está bloqueando con session_id: 67, que es la sesión uno.
La sesión con el id: 67 no será visible en sys.dm_exec_requests DMV, porque la ejecución ha finalizado, sin embargo, no se ha confirmado ni revertido. Podemos usar el comando DBCC para identificar la declaración que está causando problemas:
Eliminar fila
Entonces, estamos eliminando la fila de la tabla, tenemos un índice en la columna y estamos usando la misma columna en la cláusula WHERE en una declaración T-SQL. Sin embargo, establece un bloqueo exclusivo en la mesa hasta que se COMPROMETE o ROLLBACK. En la sesión posterior, no usamos el prefijo 'N' en la cláusula WHERE, sin embargo, la primera instrucción T-SQL ha producido el bloqueo y no está listo para liberar las sesiones en una cadena de bloqueo.

Conclusión

Los tipos de datos pueden variar entre varios sistemas de bases de datos; cada base de datos tiene tipos de datos algo diferentes y VARCHAR no significa lo mismo en todas las bases de datos. SQL Server tiene VARCHAR y NVARCHAR, pero los tipos de datos mixtos pueden causar problemas de rendimiento de consultas que son difíciles de solucionar e investigar. El mensaje para llevar es no usar el prefijo N con el tipo de datos VARCHAR en SQL Server para evitar problemas de rendimiento de consultas.

Ver más

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Post Top Ad

Your Ad Spot

Páginas