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 HAVING
las 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.
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.