Predicados “SARGABLES” 

SARGABLE viene del acrónico SARG (Search ARGument) y se refiere a una clausula WHERE que compara una columna con una constante. ¿Y eso que significa? Pues que un WHERE es SARGABLE cuando se puede apoyar en índices para mejorar la respuesta. Los WHERE NON-SARGABLE, en cambio, son aquellos que no pueden ayudarse de índices a la hora de realizar el filtrado de datos. Hay que evitar los operadores NON-SARGABLE.

Hay algunos operadores que pueden impedir (aunque no siempre) la utilización de índices en un WHERE. Los operadores en cuestión son: “IS NULL”, “<>”, “!=”, “!>”, “!<” (estos dos últimos en caso de que existan para ese motor, ya que no son comunes), “NOT”, “NOT EXIST” , “NOT IN”, “NOT LIKE”. Básicamente todas las que usan NOT)

Además, las expresiones que incluyen una función sobre una columna, comparaciones contra una columna – no es una constante – u operadores con la misma columna en ambos lados, son también NON-SARGABLE.

No obstante, hay veces que hay alguna condición con estos operadores y no significa necesariamente que el WHERE sea NON-SARGABLE, porque otra condición puede hacer que la consulta utilice un índice que evite el TABLE/INDEX SCAN (es lo que ocurre con WHERE NON-SARGABLE) y realice un COVERED INDEX sin necesidad de utilizar el índice. Esto ocurre cuando el índice incluye los campos devueltos por el SELECT y los del JOIN. Por otra parte, un WHERE puede también estar compuesto por otra clausula que tire de otro índice.

De todas formas, no siempre viene bien hacer un COVERED INDEX, ya que cuando los índices son muy extensos puede aumentar mucho la utilización de CPU y bus de Entrada / Salida, que puede resultar en algunos casos más perjudicial incluso que una query que no utilice índices.

Vamos a ver una serie de pautas que pueden llevar a mejoras de rendimiento en las consultas.

Pautas para convertir condiciones NON-SARGABLE a SARGABLE.

  • No utilizar funciones sobre columnas:

Como decíamos en la introducción, ésta es una de las causas más comunes de que una condición sea NON-SARGABLE, y muchas veces es perfectamente reescribible a una condición que no se apoye en la columna, sino en una constante (literal, parámetro).
Imaginad que queremos obtener aquellos empleados cuyo Apellido comience por la M. La query sería tal que así:

SELECT NOMBRE, APELLIDO FROM EMPLEADO WHERE SUBSTRING(APELLIDO, 1, 1) = ‘M’

Esta query utiliza sobre la columna APELLIDOS la función SUBSTR, por lo que no es SARGABLE, pero con un pequeño cambio de operador podemos tener el mismo resultado y una query SARGABLE.

SELECT NOMBRE, APELLIDO FROM EMPLEADO WHERE APELLIDO LIKE ‘M%’

Como veis, utilizando el LIKE dejamos de utilizar una función sobre la columna por lo que el WHERE pasa a ser SARGABLE. Más adelante entraremos en consideraciones particulares del operador LIKE, ya que dependiendo de algunos factores de la cadena a comparar, este puede ser NON-SARGABLE.

Otro ejemplo podría ser el de una query que buscara los proyectos que empiezan en menos de un mes de una fecha introducida por parámetro.

SELECT ID_PROYECTO FROM PROYECTO 

WHERE DATEDIFF(FECHA_INICIO , :FECHA_PARAMETRO) < 30

Esta query no es SARGABLE porque se está aplicando una función a una columna. Ahora bien, si pensamos un poco podemos sacar una query equivalente, eso sí, utilizando otro operador.

SELECT ID_PROYECTO FROM PROYECTO 

WHERE FECHA_INICIO > DATE_ADD(:FECHA_PARAMETRO , INTERVAL 30 DAYS)

  • Operador NOT

El operador NOT siempre es NON-SARGABLE, pero de igual que en el caso anterior, se pueden encontrar formas diferentes de escribir una consulta sin necesidad de usarlo.

Por ejemplo, vamos, a imaginar que nuestra tabla Empleado tiene un campo SALARIO, donde se indica la cantidad de dinero que cobra el trabajador bruto al año.

Si quisiéramos obtener aquellos trabajadores que no cobran más de 20.000€ brutos / años, nuestra primera idea podría ser ésta:

SELECT NOMBRE, APELLIDOS FROM EMPLEADO WHERE NOT SALARIO > 20.000

*También podríamos haber usado el operador !>, que funciona exactamente igual, pero este operador es muy poco común en la mayoría de motores.

Una forma muy sencillita de variar esta consulta y no utilizar el operador NOT es la siguiente:

SELECT NOMBRE, APELLIDOS FROM EMPLEADO WHERE SALARIO <= 20.000

Uso del punto y coma en T-SQL

Microsoft publica en la MSDN la “Lista de características desusadas del motor de base de datos de SQL Server 2012“. Esta lista es útil para mantener nuestra aplicación actualizada, de tal forma que podamos seguir usando las nuevas funcionalidades de las sucesivas versiones SQL Server. Mantener en nuestro código alguna característica marcada como obsoleta o en desuso implicaría que no podríamos ejecutarlo en la versión de SQL que ya no la soportase.

Pues bien, en dicha lista aparecen tanto las características que no serán soportadas en la próxima versión de SQL Server como las que estarán en desuso en futuras versiones. Esta segunda lista es muy amplia, pero si leemos detenidamente en ella nos encontraremos con, al menos, una característica que nos llamará la atención:

“No finalizar las instrucciones de Transact-SQL con un punto y coma.”

Es decir, Microsoft pretende que deje de ser opcional -como lo es hasta ahora- finalizar las sentencias SQL con o sin punto y coma. Hasta ahora, su opcionalidad ha provocado que millones de líneas de código Transact SQL se haya escrito sin punto y coma al finalizar cada sentencia. Incluso el código que Microsoft implementa en las bases de datos de sistema no incluye este símbolo final.

Así pues, parece descabellado que se pretenda que a partir de una incierta futura versión de SQL Server sea obligatorio, como así pretende Microsoft, finalizar cada sentencia con punto y coma. En tal circunstancia, todo el código anterior debería ser revisado… ¡Todo, sin excepción! No se trataría de buscar una determinada característica en él y reemplazarla, sino de cambiarlo entero. Incluso aquel programador acostumbrado a finalizar sus sentencias con dicho signo de puntuación puede haber olvidado ponerlo en alguna ocasión, ya que su T-SQL era igualmente válido.

Es impensable ponernos a revisar todo el código de la Base de Datos cuando ya está avanzada la aplicación, pero ya que Microsoft no avisa con tiempo, nos aprovechamos y a partir de ahora, cada procedimiento que modifiquemos o que hagamos nuevamente, sería una muy buena práctica cambiarlo y terminar cada sentencia con un punto y coma. Recalco que se traca de cada sentencia no cada bloque de ejecución. Para los que programamos en Delphi esto es posiblemente más sencillo, ya que es exactamente igual que si programásemos en Delphi.

Además de lo anteriormente expuesto, actualmente se pueden dar casos en los que no terminar con un punto y coma suponga errores o peor aún, que no se ejecute parte del código y ni nos enteremos.

Pongamos un ejemplo. En el código que pongo a continuación, el Sql Server no dará error.
BEGIN TRANSACTION

  EXEC ProcedureName

COMMIT TRANSACTION
Si quitamos el EXEC en la llamada al procedimiento se quitara el error, pero….. No se ejecutará la llamada al mismo, ya que el compilador pensara que comenzamos una transacción llamada “ProcedureName” pero no se ejecutará la llamada. Si en su lugar ponemos.
BEGIN TRANSACTION;

  EXEC ProcedureName;

COMMIT TRANSACTION;
Ya no habrá lugar a dudas para el compilador de cuales son las sentencias a ejecutar.

Para más información.
http://www.sqlserverya.com.ar/temarios/descripcion.php?cod=108&punto=102

http://blogs.sqlsentry.com/aaronbertrand/bad-habits-semi-colons-schema-prefix/

Control de transacciones y bloqueos en SQL Server

Agradezco a Sergio Alcalde su labor en una serie de Blogs que me han permitido aprender sobre este espinoso tema.

 

Gestión de transacciones en SQL Server

Conocer la gestión de transacciones que realiza SQL Server, qué son y cómo funcionan, es la clave para desarrollar aplicaciones eficaces y eficientes que se conectan a un gestor de bases de datos (SGBD) para consultar y modificar datos, con usuarios accediendo concurrentemente para realizar acciones de distinta naturaleza sobre los mismos (no es lo mismo consultar información que actualizarla) y teniendo que gestionar acciones de actualización que afectan a varios datos a la vez.

Sigue leyendo

Triggers de DDL para impedir modificaciones

En muchas ocasiones como DBA’s de una empresa, se nos plantea el problema de restringir a determinados usuario que puedan realizar modificaciones en las estructuras de las bases de datos. Es cierto que se puede hacer configurando permisos, pero tiene el problema de las creaciones de nuevos objetos que habrían de configurarse y ademas es un poco confuso el tratamiento de permisos, o por lo menos lo es para mi que vengo del mundo Oracle. Yo he encontrado otra alternativa.

Sigue leyendo

Premio: One Lovely Blog Award

one-lovely-blog-awardEs un honor inesperado para mi que se me conceda por parte de la comunidad de bloggers con la mención “One Lovely Blog Award”, otorgada por la Doctora Dessire Sicilia, que ademas de ser una maravillosa persona, es una excelente profesional y un blogera activa y con una ideas revolucionarias para ayudar el medio ambiente que expone en su blog www.dsicilia.com y en el de su proyecto empresarial Hortuscivitatis . Ambos blog con ideas y artículos que inspiran a mejorar nuestro planeta. Este premio, que va rulando entre bloggers me parece una idea magnífica y doblemente valorable, ya que otorga reconocimiento entre los mismos autores y favorece que sus lectores habituales se nutran de nueva información que fluye, más aún si cabe, entre las olas de la red.

La aceptación del premio además lleva implícitas tres acciones: Evidentemente el agradecimiento a aquel que lo otorgó, responder a las once preguntas que te formule y conceder el premio a otros once blogs que te agraen y que estén empezando en este maravilloso mundo bloguero!. También es cabal visitar los blogs que fueron premiados junto al tuyo e informarles de su premio. Sigue leyendo

Leer documento word y escribirlo en HTML

A todos nos ha pasado que necesitamos acceder a un documento Word desde nuestra aplicación, ya sea para escribirlo o para acceder a su contenido. Aunque esto ultimo es menos común.
Después de varios días peleándome con este formato de ficheros, he aprendido bastantes cosas y me gustaría compartirlas, ya que para algunas la información que he encontrado en internet es prácticamente nula.
Voy a intentar ordenar mis ideas.
Lo primero que nos es necesario es crear los objetos que nos permitirán acceder al word, estos son dos, el TWordapplication y el TWordDocument. Una vez hecho esto, deberemos abrir el fichero word. Hasta ahí fácil. La complicación viene cuando queremos leer el contenido del word o escribir en el. Y peor aun si lo que deseamos es saber que estilos, fuentes. Alineaciones se han aplicado.

Diferencia entre Parent y el Owner en la creación dinámica de componentes.

Aunque parece obvio, hay una gran diferencia entre el Owner de un componente y el parent del mismo.

A la hora de crear un componente de forma dinámica es muy importante tener presente la destrucción del mismo, ya que al ocupar un area de memoria, si no lo destruimos podría darnos el famoso Access Violation que tan bien todos conocemos y aborrecemos. Para evitar este problema, lo mas cómodo es crearlo con Create(Self) de manera que el Owner seria el formulario en el que lo creamos, de esta manera al destruirse el formulario, se destruirían también todos los objetos creados cuyo owner sea éste.

Si lo creamos con Create(nil) deberemos ser responsables de su destrucción.

Otro tema es el Parent de un componente. Explicándolo de forma sencilla, el parent de un componente visual es contenedor que lo contiene o sea, si ponemos un TEdit en un panel, el Parent del TEdit sera el Panel. Esta propiedad puede ser cambiada de manera dinámica a conveniencia.

Cuando solo creamos unos pocos componentes no hay mucho problema, pero si lo que creamos es un formulario completo, hay que tener muy presente estos conceptos y afinarlos muy bien, si no podemos perder mucho tiempo depurando errores.

Un nuevo comienzo

Eureka un poco tarde, pero ya tenía que migrarme a la web 2.0. Un poco por pereza y otro poco por falta de tiempo estaba retrasando lo inevitable :).
De nuevo voy a regresar a mis orígenes, dado que en los últimos años con la web anterior apenas he tenido visitas, voy a dedicar, de nuevo, la web a mi profesión, la informática. Iré posteando mis pequeñas aportaciones sobre el mundo de Delphi, Oracle y el SQL Server. Quizá las cosas que vaya averiguando en estas materias puedan ayudar a aquellos que comienzan y como no a los que como yo llevan 30 años en la informática pero nunca se cansan de aprender cosas nuevas.
Solo necesito constancia para ir escribiendo mis elucubraciones.