O que a palavra "SARGable" realmente significa?

23

Os usuários do SQL Server usam o termo "sargable" . Gostaria de saber se existe uma definição atemporal objetiva e independente de implementação para "sargable".

Por exemplo, WHERE foo LIKE '%bar%'é dito por muitos como não sargável , mas alguns RDBMSs são capazes de usar índices nessas consultas . O que significa então "não sargável" ?

Outras referências

Evan Carroll
fonte
5
Convém salientar que sua pergunta não é sobre o SQL Server, mas sobre o termo " sargable ". Sua pergunta fez referência apenas ao SQL Server porque não é capaz de lidar com predicados de pesquisa "% wordhere%", enquanto aparentemente outros RDBMS o são.
John aka hot2use

Respostas:

31

O termo "sargável" foi introduzido pela primeira vez por P. Griffiths Selinger et al. em seu artigo de 1979 "Seleção de caminho de acesso em um sistema de gerenciamento de banco de dados relacional", publicado pela ACM . Para não membros do ACM, há uma cópia desse documento em http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf

O termo é definido neste parágrafo:

As varreduras de índice e segmento 1 podem, opcionalmente, receber um conjunto de predicados, chamados argumentos de pesquisa (ou SARGS), que são aplicados a uma tupla antes de retornar ao chamador RSI 2 . Se a tupla satisfizer os predicados, ela será retornada; caso contrário, a verificação continuará até encontrar uma tupla que satisfaça o SARGS ou esgotar o segmento ou o intervalo de valores de índice especificado. Isso reduz os custos, eliminando a sobrecarga de fazer chamadas RSI para tuplas, que podem ser rejeitadas com eficiência no RSS. Nem todos os predicados têm a forma que pode se tornar SARGS. Um predicado sargável é aquele da forma (ou que pode ser colocada na forma) "valor de operador de comparação de colunas". SARGS são expressos como uma expressão booleana de tais predicados na forma normal disjuntiva.

Em outras palavras, um predicado sargável é aquele que pode ser resolvido pelo mecanismo de armazenamento (método de acesso) observando diretamente a tabela ou o registro do índice. Um predicado não sargável, por outro lado, requer um nível mais alto do DBMS para executar uma ação. Por exemplo, o resultado de WHERE lastname = 'Doe'pode ser decidido pelo mecanismo de armazenamento simplesmente olhando o conteúdo do campo lastnamede cada registro. Por outro lado, WHERE UPPER(lastname) = 'DOE'requer a execução de uma função pelo mecanismo SQL, o que significa que o mecanismo de armazenamento precisará retornar todas as linhas que lê (desde que correspondam a outros possíveis predicados sargáveis) de volta ao mecanismo SQL para avaliação, incorrendo em custos adicionais de CPU .

Você pode ver na definição original que predicados sargáveis ​​podem ser aplicados não apenas às varreduras de índice, mas também às varreduras de tabela (segmento na terminologia do System R), desde que as condições "valor de comparação de operador de coluna" sejam atendidas e, portanto, possam ser avaliado pelo mecanismo de armazenamento. Este é realmente o caso do Db2, um descendente do Sistema R de várias maneiras :

Os predicados sargáveis ​​do índice não são usados ​​para agrupar uma pesquisa, mas são avaliados a partir do índice, se um for escolhido, porque as colunas envolvidas no predicado fazem parte da chave do índice. Esses predicados também são avaliados pelo gerenciador de índices.

Os predicados sargáveis ​​de dados são predicados que não podem ser avaliados pelo gerenciador de índices, mas podem ser avaliados pelo Data Management Services (DMS). Normalmente, esses predicados requerem o acesso de linhas individuais a partir de uma tabela base. Se necessário, o DMS recuperará as colunas necessárias para avaliar o predicado,

O fato de que nos predicados sargáveis ​​de fala do SQL Server são apenas aqueles que podem ser resolvidos usando pesquisas de índice é provavelmente determinado pela incapacidade de seu mecanismo de armazenamento de aplicar esses predicados durante as verificações de tabela.

Os predicados sargáveis ​​e não-sargáveis ​​às vezes são descritos como predicados "estágio 1" e "estágio 2", respectivamente (isso também vem da terminologia Db2 ). Os predicados do estágio 1 podem ser avaliados no nível mais baixo do processamento de consultas, ao ler registros de tabela ou índice. Linhas que correspondem às condições do estágio 1, se houver, são enviadas para o próximo nível, estágio 2, de avaliação.


1 - Segmento no Sistema R é o armazenamento físico das tuplas de uma tabela; uma varredura de segmento é um pouco equivalente a uma varredura de tabela em outros DBMSes.

2 - RSI - RSS 3 Interface, uma interface de consulta orientada a tuplas. A função de interface relevante para esta discussão é NEXT, que retorna a próxima linha correspondente aos predicados de consulta.

3 - RSS, ou Research Storage System, o subsistema de armazenamento do Sistema R.

mustaccio
fonte
"observando diretamente a tabela ou o registro do índice" o que isso significa? Quero dizer, certamente = UPPER()é uma chamada de função, mas também é memcmppor si só. Seria relativamente fácil escrever um memcmpque assuma ASCII e ignore maiúsculas e minúsculas (basta ver a segunda mordidela). Isso o torna SARGÁVEL? Veja também o exemplo do @ Ypercube, dba.stackexchange.com/questions/162263/…
Evan Carroll
4
@EvanCarroll Significa olhar diretamente para a tabela ou o índice, sem recorrer às funções do banco de dados implementadas fora do mecanismo de armazenamento (por exemplo, no processador de consultas / mecanismo de execução / serviço de expressão). No exemplo do ypercube, a consulta é pré-processada pelo planejador / otimizador, de modo que a pesquisa não SARGable seja expressa em termos SARGable.
Paul White diz GoFundMonica
O que significa "olhar diretamente para a tabela ou para o registro do índice" ? Não tenho certeza de como isso está explicando "observar diretamente a tabela ou o registro do índice" . O x=0SARGable é ? Que tal -0 = +0, ' ' = ''ou igualdade espacial? O que seria um exemplo de algo que era SARGable, com certeza? Quando você diz "sem recorrer às funções do banco de dados implementadas fora do mecanismo de armazenamento", você está incluindo o exemplo do Ypercube, DATE()incluído no mecanismo de armazenamento. Por que isso não é SARGable por si só?
Evan Carroll
2
@EvanCarroll Dedique algum tempo para ler o artigo referenciado e, talvez, repasse esta resposta novamente depois disso. Se você ainda tiver perguntas que estariam no tópico aqui, você pode perguntar. Observe de passagem que DATE()não é uma função real (SQL Server), mas (presumi) a abreviação do Sr. Cube para uma conversão de tipo. Também podemos discutir isso no chat, se quiser.
Paul White diz GoFundMonica
18

Para mim, SARGable significa que o SQL Server pode executar uma pesquisa de índice usando seus predicados de pesquisa.

Você não pode simplesmente dizer que o DBMS pode "tirar proveito" de um índice, porque com um predicado não sargável, o SQL Server pode acabar varrendo um índice não clusterizado.

Brent Ozar
fonte
Eu estenderia isso para a eliminação de partições também #
441 David Markovitz
9

De acordo com o Pro SQL Server Internals de Dmitri Korotkevitch :

Um predicado Search ARgument ABLE é aquele em que o SQL SERVER pode utilizar uma operação de busca de índice, se existir um índice.

Um predicado SARGable é aquele em que o servidor SQL pode isolar o valor único ou o intervalo de valores de chave de índice a serem processados

Predicados sargable incluem os seguintes operadores: =, >, >=, <, <=, IN, BETWEEN, e LIKE( no caso de correspondência prefixo )

Operadores não sargable incluem: NOT, NOT IN, <>, e LIKE( não prefixo correspondente ), bem como o uso de funções ou cálculos contra a mesa, e tipo conversões em que o tipo de dados não satisfizer o índice criado.

Exemplo :

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;

Agora 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;

Os resultados são:

[1]

Vejamos as propriedades da consulta SARGable (busca por índice)

insira a descrição da imagem aqui

O otimizador de consulta é capaz de definir um limite no índice de início e fim. Possui um argumento de pesquisa para consulta.

Agora a consulta não-SARGable:

insira a descrição da imagem aqui

Você pode ver com o início do predicado '% non ..%' que não permite que o otimizador de consultas DEFINE um início e um final ou intervalo no índice. Agora ele deve pesquisar a tabela inteira (varredura).

Vic Work
fonte
Então, novamente, se um índice for criado posteriormente WHERE name like '%non-SARGable%'e oferecer suporte , isso tornará a condição sargável? E, nesse caso, não estamos falando de uma desvantagem específica da implementação? Ou seja, não devemos dizer "não sargável a partir do SQL Server 2016"
Evan Carroll
11
Embora haja alguma coisa nas versões do SQL Server. Embora tenha em mente que o ponto de inflexão de um índice seja um curinga no início do predicado, seria muito difícil para o otimizador de consultas definir um intervalo de valores em um índice a ser pesquisado. Assim, o uso de uma varredura e o predicado é chamado predicado não-SARGable.
Vic Work
2
Claro que é uma implementação específica. WHERE DATE(datetime_column) = '2001-01-01'por exemplo, é "sargable" (procurará por índice) nas versões mais recentes do SQL Server (acho que mais de 2008), mas não nas mais antigas.
precisa saber é o seguinte