SQL 'like' vs ' = ' performance

esta pergunta gira à volta do que estou a pensar, mas as respostas não se dirigem exactamente a ela.

parece que em geral ' = 'é mais rápido do que' gostar ' quando se usa wildcards. Esta parece ser a sabedoria convencional. No entanto, vamos supor que eu tenha uma coluna contendo um número limitado de diferentes identificadores varchar fixos, hardcoded, e eu quero selecionar todas as linhas correspondentes a uma delas:

select * from table where value like 'abc%'

e

select * from table where value = 'abcdefghijklmn'

'Como' só deve ser necessário testar os três primeiros caracteres para encontrar uma correspondência, enquanto que ' = ' deve comparar a string inteira. Neste caso, parece-me que "gostar" teria uma vantagem, sendo todas as outras coisas iguais.

Esta é uma questão geral, acadêmica, e por isso não deve importar qual DB, mas ele surgiu usando SQL Server 2005.

Author: Community, 2011-05-26

8 answers

Ver https://web.archive.org/web/20150209022016/http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx

Passo a citar:

As regras para a utilização do índice com o tipo são vagamente assim:

  • Se o seu critério de filtragem usar igual = e o campo é indexado, então a maioria é provável que use um índice / agrupamento PROCURA DO ÍNDICE

  • Se o seu critério de filtragem usar como, sem wildcards (como se você teve uma parâmetro em um relatório web que poderia ter um % , mas você em vez usar o completo string), é tão provável quanto #1 para usar o índice. O aumento dos custos quase nada.

  • Se o seu critério de filtragem usar como, mas com um carácter especial no início (como em Nome0 como '% UTER') é muito menos é provável que use o índice, mas ainda assim pode, pelo menos, efectuar uma análise de índice em uma gama completa ou parcial do Índice.

  • No entanto, se o seu filtro critérios de Utilização Tipo, mas começa com uma corda primeiro e tem wildcards em algum lugar depois disso (como em Nome0 como 'COMP % ER'), em seguida SQL pode apenas usar um índice procurar rapidamente procurar as linhas que têm o mesmo primeiro caracteres iniciais, e depois olhar através dessas linhas para uma correspondência exacta.

(também tenha em mente, o motor SQL ainda pode não usar um índice como você está esperando, dependendo do que outra coisa está acontecendo em sua consulta e em que Mesas te vais juntar. O Motor SQL reserva-se o direito de reescrever um pouco a sua consulta para obter a dados de uma forma que ele pensa é mais eficiente e que pode incluir um Pesquisa de índice em vez de pesquisa de índice)

 64
Author: BonyT, 2020-01-15 23:35:36

É uma diferença mensurável.

Passa o seguinte:

Create Table #TempTester (id int, col1 varchar(20), value varchar(20))
go

INSERT INTO #TempTester (id, col1, value)
VALUES
(1, 'this is #1', 'abcdefghij')
GO

INSERT INTO #TempTester (id, col1, value)
VALUES
(2, 'this is #2', 'foob'),
(3, 'this is #3', 'abdefghic'),
(4, 'this is #4', 'other'),
(5, 'this is #5', 'zyx'),
(6, 'this is #6', 'zyx'),
(7, 'this is #7', 'zyx'),
(8, 'this is #8', 'klm'),
(9, 'this is #9', 'klm'),
(10, 'this is #10', 'zyx')
GO 10000

CREATE CLUSTERED INDEX ixId ON #TempTester(id)CREATE CLUSTERED INDEX ixId ON #TempTester(id)

CREATE NONCLUSTERED INDEX ixTesting ON #TempTester(value)

Depois:

SET SHOWPLAN_XML ON

Depois:

SELECT * FROM #TempTester WHERE value LIKE 'abc%'

SELECT * FROM #TempTester WHERE value = 'abcdefghij'

O plano de execução resultante mostra que o custo da primeira operação, a comparação LIKE, é cerca de 10 vezes Mais caro do que a comparação =.

Se puder fazer uma comparação =, por favor faça-o.

 46
Author: JNK, 2011-05-26 19:18:34

Você também deve ter em mente que ao usar {[[0]}, alguns sabores sql irão ignorar os índices, e isso irá acabar com o desempenho. Isto é especialmente verdadeiro se você não usar o padrão "começa com" como o seu exemplo.

Você deve realmente olhar para o plano de execução para a consulta e ver o que ele está fazendo, adivinhar o mínimo possível.

Dito isto, o padrão "começa com" pode e é otimizado no servidor sql. Ele irá usar o índice da tabela. EF 4.0 mudou para like por isso mesmo.
 13
Author: Blindy, 2011-05-26 16:59:47

Se {[[0]} não estiver indexado, ambos resultam numa tabela-scan. A diferença de desempenho neste cenário será insignificante.

Se {[[0]} for indexado, como Daniel aponta no seu comentário, o {[[2]} irá resultar numa pesquisa de índice que é o(log n) Desempenho. A vontade similar (mais provável - dependendo de quão seletiva ela é) resulta em uma varredura parcial do Índice >= 'abc' e < 'abd' que irá requerer mais esforço do que o =.

Note que estou a falar de um servidor SQL. O DBMSs vai ser bom com o tipo.
 7
Author: Will A, 2011-05-26 17:02:57
Está a fazer a pergunta errada. Em bases de dados não é o desempenho do operador que importa, é sempre o Sargabilidade da expressão, e o cobertura da consulta Global. O desempenho do próprio operador é em grande medida irrelevante. Então, como é que LIKE e = se comparam em termos de Sargabilidade? LIKE, quando usado com uma expressão que não começa com uma constante (eg. quando usado LIKE '%something') é por definição não-SARGabale. Mas será que isso faz = ou LIKE 'something%' Sargável? Não. Como acontece com qualquer pergunta sobre o desempenho SQL, a resposta não está na consulta do texto, mas com o esquema implantado. Estas expressões podem ser Sargáveis se {[19] } existe um índice para as satisfazer. Então, verdade seja dita, existem pequenas diferenças entre = e LIKE. Mas perguntar se um operador ou outro operador é 'mais rápido' em SQL é como perguntar ' o que vai mais rápido, um carro vermelho ou um carro azul?'. Você deve fazer perguntas sobre o Tamanho do motor e peso vechicle, não sobre a cor... Para abordar questões sobre a otimização de tabelas relacionais, o lugar a procurar é o seu índices e suas expressões na cláusula onde (e outras cláusulas, mas geralmente começa com o onde).
 6
Author: Remus Rusanu, 2011-05-26 22:59:01

Um exemplo pessoal usando mysql 5.5: eu tinha uma junção interna entre 2 tabelas, uma de 3 milhões de linhas e uma de 10 mil linhas.

Ao usar um tipo num índice como o abaixo (sem wildcards), levou cerca de 30 segundos:

where login like '12345678'

Usando o 'explain' recebo:

enter image description here

Ao usar um ' = ' na mesma consulta, levou cerca de 0, 1 segundos:

where login ='600009'

Usando o 'explain' recebo:

enter image description here

Como pode ver, o like cancelou completamente a pesquisa de índice, a consulta demorou 300 vezes mais tempo.

 5
Author: Aris, 2015-02-19 15:12:13

Talvez estejas a olhar para procura por texto completo .

Em contraste com a pesquisa de texto completo, o predicado Transact-SQL funciona em apenas padrões de carácter. Além disso, você não pode usar o predicado similar para pesquisa formatada dados binários. Além disso, uma pergunta semelhante contra uma grande a quantidade de dados de texto não estruturados é muito mais lenta do que um equivalente pesquisa de texto completo contra os mesmos dados . Uma consulta semelhante contra milhões de linhas de dados de texto pode levar minutos a voltar; que um texto completo a consulta pode levar apenas segundos ou menos contra os mesmos dados, dependendo no número de linhas que são devolvidas.

 0
Author: , 2016-11-06 07:33:50

Primeiro O Mais Importante,

Nem sempre são iguais

    select 'Hello' from dual where 'Hello  ' like 'Hello';

    select 'Hello' from dual where 'Hello  ' =  'Hello';
Quando as coisas nem sempre são iguais, falar do seu desempenho não é relevante.

Se você está trabalhando em strings e apenas em variáveis de char, então você pode falar sobre o desempenho . Mas não use como e " = " como sendo geralmente intercambiáveis .

Como você teria visto em muitos posts ( acima e outras perguntas), nos casos em que eles são iguais o desempenho de semelhante é mais lento devido para correspondência de padrões (collation)

 -1
Author: user5190021, 2015-08-04 14:17:36