Grimpi IT Blog

marzo 19, 2011

Monitorear el progreso de una operación masiva de INSERT/DELETE sobre una tabla

Filed under: SQL Server, T-SQL — grimpi @ 11:47 pm

Supongamos que queremos monitorear el progreso de una operación intensiva de insert/delete sobre una tabla dentro de una transacción.
La primera opción que uno piensa es hacer un SELECT COUNT(*) FROM Tabla a medida que se ejecuta la operación de insertado
o borrado de datos. Lamentablemente salvo que tengamos un isolation level muy bajo, esta consulta va a quedar bloqueada
hasta que se termine la ejecución de la otra transacción, por lo tanto, no vamos a poder monitorear el progreso de la misma.

Veamos este ejemplo:

INSERT INTO TablaCliente (ID, Nombre, Apellido)
SELECT ID, Nombre, Apellido FROM ServidorLinkeado.dbo.MaestroClientes

Yo quiero copiar el contenido de la tabla MaestroClientes de un servidor externo a mi base de datos. Supongamos que la tabla MaestroClientes contiene 20 millones de registros, lo que significa que aun en optimas condiciones, el proceso seguramente duraría al menos un par de minutos.
Ahora mientras se ejecuta el INSERT de mas arriba, hagamos un SELECT COUNT(*) FROM TablaCliente en otra sesión. Como verán, la consulta queda en espera, hasta que se termine la transacción que realiza el insertado de datos.
Sin embargo, si consultamos la vista de sistema sys.partitions, vamos a encontrar información muy interesante, especialmente en el campo Rows. Consultando esta vista para la tabla que deseamos monitorear a medida que se ejecuta la transacción, vamos a ver que el campo rows de esa vista varia.

Ejemplo:

SELECT object_id, rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

A diferencia del SELECT COUNT(*) que hacíamos antes, esta consulta no queda bloqueada, pudiendo ser ejecutada varias veces mientras se realiza la transacción de insertado.
Entonces, como hacemos para ver el porcentaje de progreso?

1) Capturamos el total de registros que vamos a insertar:
SELECT COUNT(*) FROM ServidorLinkeado.dbo.MaestroClientes.

2) Capturamos el total de registros que ya existe en la tabla de destino:
SELECT rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

3) Ejecutamos la transacción que realiza el insertado masivo de datos:
INSERT INTO TablaCliente (ID, Nombre, Apellido)
SELECT ID, Nombre, Apellido FROM ServidorLinkeado.dbo.MaestroClientes

4) Mientras se ejecuta la transacción, abrimos una nueva conexión y ejecutamos reiteradamente esta consulta:
SELECT rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

 

 

Exactamente aplica la misma lógica, en el caso de que nos interese monitorear una operación de DELETE. La única diferencia es que en la columna rows de la tabla sys.partitions, veremos que su número desciende sucesivamente.

marzo 11, 2011

Cosas piolas que debería traer la nueva versión de SQL Server:

Filed under: Opinion, SQL Server, T-SQL — grimpi @ 2:13 pm

1) Encriptación irreversible por columna (similar al COLUMN ENCRYPT de Oracle). Ideal para almacenar passwords.

2) Agregar la sentencia CREATE OR REPLACE PROCEDURE/VIEW/FUNCTION como ya tienen Oracle o PostgreSQL. De esta manera, con una sola sentencia, nos evitamos verificar si existe o no una vista, store procedure o una función cuando deployamos.

3) CREATE TABLE NuevaTablaCliente AS TableClienteExistente. La posibilidad de crear una nueva tabla copiando la estructura de otra tabla ya existente es una feature muy piola de PostgreSQL.

4) ALTER COLUMN NombreColumn SET IDENTITY ON/OFF. Habilitar/deshabilitar un campo identity sin necesidad de reconstruir toda la tabla.

5) @NuevoParametro TablaCliente.ClienteId%TYPE. Poder declarar un parametro o variable como tipo de dato de una columna, en vez de declarar explicitamente el tipo de dato como hacemos actualmente.

6) Indíces Bitmap como los de Oracle.

7) Una funcion DECODE similar a la de Oracle (para el que no la conoce, es una especie de CASE…WHEN en una funcion).

8) Que no haya que configurar 50 parametros de Windows y DTC para poder correr una transacción distribuida correctamente.

9) Tener una función de conversión y formateo de datos potente, amigable y facil de usar, y no ese engendro de CONVERT.

10) Una función de SPLIT de string nativa para T-SQL que devuelva una variable de tabla.

11) ALTER TABLE para cambiar el orden de una columna en una tabla. Si bien es un poco “polémica” esta feature (se supone que el orden de las columnas no debería importarnos), la realidad es que a veces termina siendo útil. MySql tiene esta posibilidad.

12) Mejorar el error “String or binary data would be truncated.” cuando insertamos o modificamos datos. En que columna? Que valor fue el que tiro error? Si lo sabes, porque SQL Server no me lo queres decir?

13) Que soporte este tipo de sentencias: SELECT * FROM Clientes WHERE (col1, col2) NOT IN (SELECT col1, col2 FROM OtrosClientes). Actualmente el IN o NOT IN solo lo podemos hacer con una sola columna.

Alguna otra sugerencia?

marzo 3, 2011

Herramientas fundamentales para el desarrollo:

Filed under: .NET, Links — grimpi @ 12:01 pm

  • Notepad++. Es el excelente reemplazo al famoso UltraEdit, pero open source. Indispensable.
  • HeidiSQL: No se si es la mejor IDE de MySql gratuita que existe, pero le pega en palo. Lo mejor de todo, es que es un solo archivo .exe. No tiene dependencias ni dll ni requiere instalación.
  • .NET Reflector: De Red Gate. La mejor herramienta de reflector para .net. Hay que aprovechar a bajarla ahora, porque es gratis solo hasta el 30 de mayo del 2011.
  • Visual Studio Productivity Power Tools: Es un Add-In para Visual Studio con algunas boludeses que nos mejorar la calidad de vida. Recomendado.
  • ReSharper: No es gratis, pero para mi es fundamental. Se puede conseguir legalmente gratis si demostramos que participamos de algún proyecto open source.
  • Open DBDiff: Para comparar bases de datos SQL Server :)
  • NuGet: Es un Add-in para el Visual Studio. Ya no es necesario buscar manualmente librerías y Add-Ins. Con NuGet la vida es mas sencilla. Así de simple.
  • PDFSharp: La mejor librería open source para generar PDF en .NET. No busque otra.
  • 7-Zip: No es una herramienta de desarrollo, sino un compresor de archivos. Pero siendo open source y comprimiendo mas cualquier otro formato, no entiendo como todavía hay gente que usa el WinRar (y ni hablar de los que usan WinZip…)
  • FileZilla: El mejor cliente de FTP que existió, existe y existirá. Y encima gratis. El que no este de acuerdo con esta afirmación, que no lea mas este blog :)
  • Dependency Explorer: Nos informa que dll y componentes le esta faltando a una aplicación. Es una herramienta de los 90. Usada mucho por los desarrolladores de Visual Basic 6 y tecnologías COM. Sin embargo, mucha veces la necesitamos hoy en día.
  • Selenium: Para testing de paginas web. Imperdible.
  • Firebug: Si no usamos Chrome, el mejor Add-in de Firefox para trabajar con Javascript, CSS, Ajax, etc…
  • Regular Expression Designer: No se si es la mejor, pero es una excelente herramienta para trabajar y testear expresiones regulares. Y Gratis.
  • AnkhSVN: Cliente de SVN para Visual Studio. No puedo decir que es una excelente herramienta, porque a veces lo puteo un poco. Pero es la que mejor se integra con Visual Studio.
  • WinMerge: Excelente herramienta para comparar archivos y directorios.
  • Compumap: Nada que ver el desarrollo ni bases de datos. Simplemente quería elogiar esta excelente herramienta para buscar colectivos en Buenos Aires. Incluso funciona en Windows 3.1!!!!!

marzo 1, 2011

Filosofía del Software: De Karl Popper a TDD y Selenium

Filed under: Arquitectura, Test Driven Development, Testing — grimpi @ 8:59 pm

Karl Popper junto con Kuhn, fueron probablemente los dos epistemólogos mas importantes del siglo pasado. El aporte más significativo que le debemos a Popper, es el falsacionismo como método de constrastación de una teoría científica.
Que dice el falsacionismo? Básicamente que no es posible probar la verdad de una teoría, pero si podemos refutarla. Entonces, un enunciado científico estaría vigente siempre y cuando, no haya podido ser refutado. Por ejemplo, si mi enunciado dice “No existe vida extraterrestre”, no existe forma de comprobar si este enunciado es verdadero, pero lo aceptamos mientras no se descubra vida exterior. Pero si se descubriera, entonces estaríamos en condiciones de decir la teoría que afirmaba que no existía vida extraterrestre era falsa.
Popper insistía mucho que las teorías científicas debían intentar ser falseadas lo máximo posible. Una buena teoría, es aquella que pudo superar exitosamente muchos intentos de falsearla.
Bien, y que tiene que ver esto con el software?

Todo. El software es excelente ejemplo de la corriente falsacionista popperiana. Jamás podremos decir que un software no tiene bugs. Pero no porque somos humanos y cometemos errores y la perfección es algo divino. No podemos decir que nuestro software no tiene bugs porque no hay forma de demostrarlo afirmativamente. Sin embargo, si podemos llegar a falsear esta afirmación si encontramos errores en el software que diseñamos.
Al igual que lo que afirmaba Popper, un buen software es aquel que ha pasado exitosamente muchos intentos por refutarlo (en nuestro caso, por hacerlo fallar).
El problema que testear un software, es una tarea compleja que debe ser llevada por distintas personas. Como ser un buen popperiano mientras testeamos?

  • Uso intensivo de pruebas unitarias: No importa si usamos TDD, BDD, TAD. No importa si usamos mocking o no. No importa si usamos xUnit, VSUnit, NUnit o no. Lo mas importante de todo, es que nuestro código tenga la mayor cantidad posible de pruebas unitarias (o de integración) posibles. Y esto no significa hacer un método de prueba por método de clase, sino tal vez, hacer varias pruebas unitarias por un solo método, si este es bastante complejo.
    Si nuestra clase esta expuesta para otros desarrollos, hay que probar también que pasa cuando se le ingresan valores no esperados (parámetros nulos, valores aleatorios totalmente fuera del rango esperado, etc.).
    Muchos programadores se sienten demasiado seguros cuando tienen muchos test unitarios en “green flag”. Sin embargo, este tipo de metodología lo que mejor garantiza es que una modificación de código no produzca que otro pedazo de código deje de funcionar. Pero no es suficiente.
    Las pruebas unitarias pueden no enfocarse solamente en probar el código base (sea C#, Java, Ruby o lo que fuese), sino también se podría hacer con Javascript y objetos de una base de datos.
  • Hacer stress testing: Muchas aplicaciones son desarrolladas en entornos incorrectos con un volumen de datos muy bajo en relación con el entorno que va a existir en producción. Esto es un gravísimo error. Porque después se sube la aplicación a producción, pensando que tiene una performance aceptable y nos encontramos al poco tiempo, con que las consultas a la base no estaban optimizadas, no hay estrategia de cacheo de datos, hay métodos que hacen uso intensivo del procesador que están mal programados y nos encontramos en producción con un montón de problemas de performance que no tuvimos en cuenta por desarrollar en un entorno muy distinto al real.
    Esto suele suceder por varias razones. En primer lugar, cuando desarrollamos una aplicación de cero, no tenemos un conjunto de datos reales de producción, entonces nuestras tablas están semivacías con los datos mínimos para poder desarrollarla. Todo funciona rapidísimo, nuestros reportes vuelan. Ahora cuando la tabla pasa de tener 20 registros a 5 millones en producción, recibimos un llamado diciendo “Houston, tenemos un problema…”
    Si no tenemos datos reales para desarrollar, debemos simularlos. Esto se puede hacer manualmente o con muchas herramientas que existen en el mercado. Visual Studio 2008/2010 tiene esa posibilidad. También Red Gate tiene un producto que se llama SQL Data Generator muy bueno.
    Es lo que se llama un test de carga de datos (Load testing).
    Otra situación que nos presente inconveniente es la concurrencia. Y esto es algo mucho más difícil de simular en desarrollo. Tener una base de datos grande es fácil. Ahora como hacemos para tener 10.000 usuarios concurrentes para desarrollo? Imposible. La mejor manera de hacer esto entonces es usar herramientas de stress testing que simulen un cuadro así. En Java existe una excelente herramienta llamada JMeter. Visual Studio ofrece una herramienta parecida (Web Application Stress). Existe este excelente portal con un compilado de distintas aplicaciones open source y gratuitas de testeo muy recomendable.
    Es lo que se llama un stress testing de concurrencia (Stress testing).
  • Test de funcionalidad: Bueno, este es el punto fuerte de QA. En una organización grande no puede faltar. Se debe verificar que el sistema haga lo que esta contemplado que haga. Se debe tener un buen documento de casos de usos y que resultados se esperan. En una empresa donde el testeo es mas “casero”, una de los principios básicos es que el que desarrollo la aplicación, no debe testearla.
    Una muy buena herramienta para automatizar test funcionales de aplicaciones web es Selenium.
  • Test de UI: Esta relacionado con el test de funcionalidad, pero se dedica a buscar errores en la UI (que son mucho mas difíciles de ser detectados en una prueba unitaria). Las validaciones son correctas? Que pasa si se deja campos en blanco o se ingresan valores extremos? Se pide confirmación cuando se van a realizar una operación de borrado o critica del negocio? Como funciona en distintas configuraciones regionales y en distintas resoluciones de pantalla? Como se muestran los errores de aplicación? Como funciona en los distintos navegadores? Que pasa si deshabilito la ejecución de javascript?
    También se deben probar elementos relacionados con la seguridad. Que pasa si modifico manualmente los valores de un querystring? Esta cubierta contra ataques de SQL Injection y XSS Injection? Que pasa si una aplicación externa intenta inyectar peticiones GET y POST a nuestra aplicación?
    WaitR y WaitN (lamentablemente discontinuado) son muy buenas herramientas para automatizar este tipo de test. También podemos usar Selenium.

Links Interesantes:
Performance Testing Guidance for Web Applications
Open Source Testing

Blog de WordPress.com.