Skip to content

Optimización de queries con SQL Server – Parte 2

  • by

Hola de nuevo! 👋

Ya estoy de vuelta por acá, después de varias semanas de mucho trabajo y muy intensas. Como les decía en mi post anterior, en esta seria voy a estar platicando sobre optimización y diseño de nuestros queries para optimizar el performance.

En esta ocasión, vamos a ver las condiciones de búsqueda sargable. Sargable es una contracción de la frase “Search ARGument ABLE”, o sea, argumentos de búsqueda, pero creo que suena más padre en inglés.

¿QUÉ ES UNA CONDICION SARGABLE?

Una “condición sargable”, o “predicado sargable” o “sargable predicate” no es mas que una condición que permite utilizar un índice. La habilidad del optimizador de utilizar un índice depende de la selectividad (¿es esa una palabra? 🤔) o “selectivity” de la condición de búsqueda, que a su vez también depende de la selectividad de la columna en nuestra cláusula WHERE, ON o HAVINGlas cuales son referenciadas en las estadísticas del índice.

El predicado utilizado en nuestra cláusula WHERE determina si el índice puede realizar alguna operación en la columna.

LAS CONDICIONES SARGABLE Y NON-SARGABLE MÁS COMUNES

Tipo Condición
Sargable =, >, >=, <, <=, BETWEEN, y algunas condiciones LIKE como  LIKE '<a buscar>%'
Non sargable <>, !=, !>, !<, NOT EXISTS, NOT IN, OR, y otras variantes de LIKE como LIKE '%<a buscar>%'

Las condiciones “sargables” en esta tabla, permiten el uso de índices en las columnas definidas en nuestra cláusula WHERE, generalmente permiten a SQL Server realizar un Index Seek y traer la fila o el rango de filas.

Por el otro lado, las condiciones “non sargables” de la tabla, no dejan a SQL Server utilizar índices eficientemente en las columnas referidas en nuestro WHERE, o sea que en ocasiones no le permiten  a SQL Server usar Index Seek como método para tarer las filas , y tiene que escanear toda la tabla hasta identificar las que coincidan con nuestra condición. Por ejemplo: la condición “!=”

EJEMPLOS UTILIZANDO CONDICIONES SARGABLE Y NON-SARGABLE

Vamos a ver algunos ejemplos usando algunas condiciones de la tabla de arriba, y les muestro los planes de ejecución para que puedan notar la diferencia.

BETWEEN VS IN VS OR

Vean el siguiente query, que se puede escribir de diferente manera utilizando OR y BETWEEN.

USE TestDB
GO

SET STATISTICS IO, TIME ON;

-- Usando IN
SELECT 
    * 
FROM
    Orders
WHERE
    OrderID IN (10260,10261,10262,10264,10265,10266,10267,10268);

-- Usando OR
SELECT 
    * 
FROM 
    Orders
WHERE
    OrderID = 10260
OR  OrderID = 10261
OR  OrderID = 10262
OR  OrderID = 10264
OR  OrderID = 10265
OR  OrderID = 10266
OR  OrderID = 10267
OR  OrderID = 10268;

-- Usando BETWEEN
SELECT 
    * 
FROM
    Orders
WHERE
    OrderID BETWEEN 10260 AND 10268

Aquí están los planes de ejecución de los tres queries.

Planes de ejecución

A simple vista se ve que son iguales, un Index Seek y todos le costaron lo mismo a SQL Server. Hasta aquí todo bien. Peeeeeero, si se hacen poquito para arriba, se darán cuenta que habilité SET STATISTICS IO, TIME ON; en los queries, que sirve para que SQL Server nos de información sobre el tiempo de ejecución y las operaciones que tuvo que realizar para traer nuestra información. Veamos…

Los mensajes están en orden para nuestros queries. Si vemos con cuidado, el primer y segundo query son casi exactamente lo mismo, ambos tienen un Scan Count de 8, esto quiere decir que tuvo que recorrer nuestro índice 8 veces, y tuvo que hacer 16 logical reads que son la cantidad de páginas en el índice, y tomaron entre 67 y 68 ms en ejecutarse.

Ahora, si revisamos los mensajes del tercer query (en el que usamos BETWEEN), vemos que solamente tuvo que recorrer el índice 2 veces, y leer nada más 2 páginas para traer la información que le pedimos. Y a pesar que tardó unos cuantos milisegundos más en ejecutarse, este query fue más eficiente que los otros dos.

Los primeros dos queries son prácticamente iguales, porque SQL Server tuvo que convertir nuestra cláusula IN en 8 condiciones OR. Ese milisegundo de más que tomó el segundo query, me imagino que fue por esa conversión que tuvo que hacer (la neta no sé, SQL Server a veces hace cosas raras y no nos dice por qué hasta que escarbamos bien 😋).

Hasta aquí le voy a dejar. En el próximo post les voy a dar más ejemplos de este tipo de condiciones y las diferencias en performance, que como ya vieron, son casí imperceptibles. Pero , ¿se imaginan ese query que tuvo que escanear el índice 8 veces, ejecutado por miles de personas, miles de veces en el día 🤯?

Bueno, ya me despido y los veo en el siguiente, espero les haya gustado. Gracias por leérme, los veo luego, cheers! 🍻


Discover more from Ben Rodríguez

Subscribe to get the latest posts sent to your email.

Discover more from Ben Rodríguez

Subscribe now to keep reading and get access to the full archive.

Continue reading