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.
8 answers
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)
É 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.
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 paralike
por isso mesmo.
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 =
.
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).
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:
Ao usar um ' = ' na mesma consulta, levou cerca de 0, 1 segundos:
where login ='600009'
Usando o 'explain' recebo:
Como pode ver, o like
cancelou completamente a pesquisa de índice, a consulta demorou 300 vezes mais tempo.
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.
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)