¿Qué significa realmente la palabra "SARGable"?

23

Los usuarios de SQL Server usan el término "sargable" . Me pregunto si existe una definición atemporal objetiva e independiente de la implementación para "sargable".

Por ejemplo, WHERE foo LIKE '%bar%'muchos dicen que no son modificables , pero algunos RDBMS pueden usar índices en tales consultas . ¿Qué significa entonces "no sargable" ?

Otras referencias

Evan Carroll
fuente
55
Es posible que desee señalar que su pregunta no es sobre SQL Server, sino sobre el término " sargable ". Su pregunta solo hace referencia a SQL Server porque no puede manejar predicados de búsqueda "% wordhere%", mientras que aparentemente otros RDBMS sí lo son.
John también conocido como hot2use el

Respuestas:

31

El término "sargable" fue introducido por primera vez por P. Griffiths Selinger et al. en su artículo de 1979 "Selección de ruta de acceso en un sistema de gestión de bases de datos relacionales", publicado por ACM . Para los que no son miembros de ACM hay una copia de ese documento en http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf

El término se define en este párrafo:

Los escaneos de índice y segmento 1 pueden tomar opcionalmente un conjunto de predicados, llamados argumentos de búsqueda (o SARGS), que se aplican a una tupla antes de que se devuelva al llamador RSI 2 . Si la tupla satisface los predicados, se devuelve; de lo contrario, la exploración continúa hasta que encuentra una tupla que satisface los SARGS o agota el segmento o el rango de valores de índice especificado. Esto reduce el costo al eliminar la sobrecarga de hacer llamadas RSI para tuplas que pueden ser rechazadas eficientemente dentro del RSS. No todos los predicados son de la forma que puede convertirse en SARGS. Un predicado sargable es uno de forma (o que se puede poner en el formulario) "valor de operador de comparación de columna". Los SARGS se expresan como una expresión booleana de dichos predicados en forma disyuntiva normal.

En otras palabras, un predicado sargable es tal que puede ser resuelto por el motor de almacenamiento (método de acceso) observando directamente la tabla o el registro de índice. Un predicado no sargable, por el contrario, requiere un nivel superior del DBMS para tomar medidas. Por ejemplo, el WHERE lastname = 'Doe'motor de almacenamiento puede decidir el resultado de simplemente mirando el contenido del campo lastnamede cada registro. Por otro lado, WHERE UPPER(lastname) = 'DOE'requiere la ejecución de una función por el motor SQL, lo que significa que el motor de almacenamiento tendrá que devolver todas las filas que lee (siempre que coincidan con otros posibles predicados sargable) al motor SQL para su evaluación, incurriendo en costos adicionales de CPU .

Puede ver en la definición original que los predicados sargable pueden aplicarse no solo a los escaneos de índice, sino también a los escaneos de tabla (segmento en la terminología del Sistema R), siempre que se cumplan las condiciones "valor de operador de comparación de columna" y, por lo tanto, se puedan cumplir evaluado por el motor de almacenamiento. De hecho, este es el caso con Db2, un descendiente del Sistema R de muchas maneras :

Los predicados de índice sargable no se utilizan para delimitar una búsqueda, pero se evalúan a partir del índice si se elige uno, porque las columnas involucradas en el predicado son parte de la clave de índice. Estos predicados también son evaluados por el administrador de índices.

Los predicados de datos sargable son predicados que el administrador de índices no puede evaluar, pero los Servicios de administración de datos (DMS) pueden evaluar. Por lo general, estos predicados requieren el acceso de filas individuales desde una tabla base. Si es necesario, DMS recuperará las columnas necesarias para evaluar el predicado,

El hecho de que en SQL Server-speak los predicados sargable son solo aquellos que pueden resolverse mediante búsquedas de índice probablemente esté determinado por la incapacidad de su motor de almacenamiento para aplicar dichos predicados durante los escaneos de tablas.

Los predicados sargable y no sargable a veces se describen como predicados "etapa 1" y "etapa 2" respectivamente (esto también proviene de la terminología Db2 ). Los predicados de la etapa 1 se pueden evaluar en el nivel más bajo de procesamiento de consultas, mientras se leen registros de tablas o índices. Las filas que coinciden con las condiciones de la etapa 1, si las hay, se envían al siguiente nivel, etapa 2, de evaluación.


1 - El segmento en el Sistema R es el almacenamiento físico de las tuplas de una tabla; una exploración de segmento es algo equivalente a una exploración de tabla en otros DBMS.

2 - RSI - RSS 3 Interface, una interfaz de consulta orientada a tuplas. La función de interfaz relevante para esta discusión es NEXT, que devuelve los predicados de consulta de coincidencia de la siguiente fila.

3 - RSS, o Research Storage System, el subsistema de almacenamiento del Sistema R.

mustaccio
fuente
"observando directamente la tabla o el registro de índice" ¿qué significa eso? Quiero decir que ciertamente = UPPER()es una llamada a la función, pero también lo es memcmppor sí misma. Sería relativamente fácil escribir un memcmpque asuma ASCII e ignore el caso (solo mire el segundo mordisco). ¿Eso lo hace SARGABLE? Vea también el ejemplo de @ Ypercube, dba.stackexchange.com/questions/162263/…
Evan Carroll,
44
@EvanCarroll Significa mirar directamente la tabla o el registro de índice, sin recurrir a las funciones de la base de datos implementadas fuera del motor de almacenamiento (por ejemplo, dentro del procesador de consultas / motor de ejecución / servicio de expresión). En el ejemplo de ypercube, la consulta es preprocesada por el planificador / optimizador de modo que la búsqueda no SARGable se expresa en términos SARGable.
Paul White reinstala a Monica
¿Qué significa "mirar la tabla o el registro de índice directamente" ? No estoy seguro de cómo eso explica "observar directamente la tabla o el registro de índice" . ¿Es x=0SARGable? ¿Qué pasa con -0 = +0, ' ' = ''o la igualdad espacial? ¿Cuál sería un ejemplo de algo que fuera SARGable, seguro? Cuando dice "sin recurrir a las funciones de la base de datos implementadas fuera del motor de almacenamiento" , está incluido en el ejemplo de Ypercube DATE()que se incluye dentro del motor de almacenamiento. ¿Por qué no es SARGable por sí mismo?
Evan Carroll
2
@EvanCarroll Tómese un tiempo para leer el documento al que se hace referencia, y tal vez revise esta respuesta nuevamente después de eso. Si todavía tiene preguntas sobre el tema aquí, puede hacerlas. Tenga en cuenta de paso que DATE()no es una función real (SQL Server), pero (supuse) la taquigrafía del Sr. Cube para una conversión de tipo. También podemos discutir esto en el chat si lo desea.
Paul White reinstala a Monica
18

Para mí, SARGable significa que SQL Server puede realizar una búsqueda de índice utilizando sus predicados de búsqueda.

No puede decir simplemente que el DBMS puede "aprovechar" un índice, porque con un predicado no compatible, SQL Server puede terminar escaneando un índice no agrupado.

Brent Ozar
fuente
También extendería eso a la eliminación de particiones
David דודו Markovitz
9

De acuerdo con Pro SQL Server Internals por Dmitri Korotkevitch :

Un predicado ABLE de argumento de búsqueda es aquel en el que SQL SERVER puede utilizar una operación de búsqueda de índice, si existe un índice.

Un predicado SARGable es aquel en el que el servidor SQL puede aislar el valor único o el rango de valores de clave de índice para procesar

Predicados sargable incluyen los siguientes operadores: =, >, >=, <, <=, IN, BETWEEN, y LIKE( en el caso de emparejamiento de prefijo )

Los operadores no sargable incluyen: NOT, NOT IN, <>, y LIKE( no coincidencia de prefijo ), así como el uso de funciones o cálculos contra la mesa, y conversiones de tipo donde el tipo de datos no cumple el índice creado.

Ejemplo :

WHERE name like 'SARGable%'
WHERE name like '%non-SARGable%'

Demo :

DROP TABLE dbo.Testing;
GO

CREATE TABLE Testing (
    WeirdDatatype   int NOT NULL,
    SomethingElse   char(200)
);

CREATE NONCLUSTERED INDEX IDX_ALWAYS_SARGable
    ON dbo.Testing( SomethingElse);

CREATE NONCLUSTERED INDEX IDX_NOT_ALWAYS_SARGable
    ON dbo.Testing(SomethingElse);

INSERT INTO dbo.Testing
        ( WeirdDatatype, SomethingElse )
SELECT TOP 1000 m.message_id, CONVERT(char(200), m.text)
FROM sys.messages AS m;

Ahora corremos:

SELECT *
FROM dbo.Testing AS t
WHERE  t.WeirdDatatype = 1001;
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE 'Line%'
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE '%Line%'
     AND t.WeirdDatatype = 1001;

Los resultados son:

[1]

Veamos las propiedades de la consulta SARGable (Index Seek)

ingrese la descripción de la imagen aquí

El optimizador de consultas puede definir un límite en el índice de inicio y fin. Tiene un argumento de búsqueda para consultar.

Ahora la consulta no SARGable:

ingrese la descripción de la imagen aquí

Puede ver que con el comienzo del predicado '% non ..%' no permite que el optimizador de consultas DEFINE un inicio y final o rango en el índice. Ahora debe buscar en toda la tabla (escaneo).

Vic Work
fuente
Entonces, de nuevo, si luego se crea un índice que admite, WHERE name like '%non-SARGable%'¿eso hace que la condición sea modificable? Y, si es así, ¿no estamos hablando de un inconveniente de implementación específico? IE., ¿No deberíamos decir "no sargable a partir de SQL Server 2016"
Evan Carroll
1
Aunque cualquier cosa es posible en las versiones de SQL Server. Si bien teniendo en cuenta el punto de inflexión de un índice, un comodín al comienzo del predicado sería muy difícil para el optimizador de consultas definir un rango de valores dentro de un índice para buscar. Por lo tanto, el uso de una exploración y el predicado se denomina predicado no SARGable.
Vic Work
2
Por supuesto, es una implementación específica. WHERE DATE(datetime_column) = '2001-01-01'por ejemplo, es "sargable" (buscará el índice) en las versiones más nuevas de SQL Server (2008+, creo) pero no en las más antiguas.
ypercubeᵀᴹ