Pergunta

Ao usar SQL, existem benefícios de usar = em uma cláusula WHERE vez de LIKE?

Sem qualquer operadores especial, LIKE e = são os mesmos, certo?

Foi útil?

Solução

diferentes operadores

LIKE e = são diferentes operadores. A maioria das respostas aqui focar o apoio de curinga, que não é a única diferença entre estes operadores!

= é um operador de comparação que opera em números e strings. Ao comparar cordas, o operador de comparação compara cordas inteiras .

LIKE é um operador de cadeia que compara caractere por caractere .

Para assuntos complicar, os operadores usar um agrupamento que pode ter efeitos importantes sobre o resultado da comparação.

motivar Exemplo

Vamos primeiro identificar um exemplo onde estes operadores produzem, obviamente, resultados diferentes. Permitam-me citar o manual do MySQL:

Por padrão SQL, funciona como correspondentes em uma base per-caráter, assim ele pode produzir resultados diferentes do = operador de comparação:

mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
|                                    1 |
+--------------------------------------+

Por favor, note que esta página do manual MySQL é chamado Funções de Comparação de Strings , e = não é discutido, o que implica que = não é estritamente uma função de comparação de cadeia.

Como o = trabalho?

O SQL padrão § 8.2 descreve como = compara strings:

A comparação das duas cadeias de caracteres é determinada da seguinte forma:

a) Se o comprimento em caracteres de X não é igual ao comprimento em caracteres de Y, em seguida, a cadeia mais curta é eficaz substituída, para efeitos de comparação, com uma cópia do -se que foi estendido para o comprimento do mais longo string concatenação sobre o direito de um ou mais pad personagens, onde o personagem pad é escolhido com base no CS. E se CS tem o atributo NO PAD, então o personagem pad é um diferente caráter dependente da implementação de qualquer personagem no conjunto de caracteres de X e Y, que intercala menos do que qualquer cadeia sob CS. Caso contrário, o personagem do rato é uma .

b) O resultado da comparação de X e Y é dada pela seqüência de agrupamento CS.

c) Dependendo da sequência de agrupamento, duas cordas pode são considerados iguais, mesmo que sejam de diferentes comprimentos ou conter diferentes sequências de caracteres. Quando as operações MAX, MIN, distinto, as referências a um agrupamento de coluna, e o União, a menos, e operadores INTERSECT referem-se a caráter cordas, o valor específico seleccionado por estas operações a partir de um conjunto de tais valores iguais é dependente de implementação.

(ênfase adicionado).

O que isso significa? Isso significa que quando comparando strings, o operador = é apenas um wrapper fino ao redor do agrupamento atual. Um agrupamento é uma biblioteca que tem várias regras para comparação de strings. Aqui está um exemplo de um binário agrupamento de MySQL :

static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
                               const uchar *s, size_t slen,
                               const uchar *t, size_t tlen,
                               my_bool t_is_prefix)
{
  size_t len= MY_MIN(slen,tlen);
  int cmp= memcmp(s,t,len);
  return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}

Este agrupamento especial acontece para comparar byte a byte (que é por isso que é chamado de "binário" - isso não dá qualquer significado especial para cordas). Outros agrupamentos podem fornecer comparações mais avançados.

Por exemplo, aqui é um UTF 8 agrupamento que as comparações de suportes de maiúsculas e minúsculas. O código é muito longo para colar aqui, mas ir para esse link e leia o corpo de my_strnncollsp_utf8mb4(). Este agrupamento pode processar vários bytes de cada vez e pode aplicar-se várias transformações (tais como o caso comparação insensível). O operador = é completamente abstraídados caprichos do agrupamento.

Como o LIKE trabalho?

O SQL padrão § 8.5 descreve como LIKE compara strings:

O

M LIKE P

é verdadeiro se existe uma partição de M em substrings tal que:

i) Uma subcorrente de M é uma sequência de 0 ou mais contíguos S de M e cada caractere < representação> de M faz parte de exatamente um substring.

ii) Se o i-ésimo especificador subsequência de P é um arbitrária especificador personagem, o i-th substring de M é um único .

iii) Se o i-th especificador substring de P é uma cadeia arbitrária especificador, em seguida, o i-ésimo subsequência de M é qualquer sequência de 0 ou mais s.

iv) Se o i-ésimo especificador subsequência de P não é nem um especificador de caráter arbitrário nem um especificador cadeia arbitrária, em seguida, o i-ésimo subsequência de M é igual ao que subcadeia especificador de acordo com a sequência de agrupamento de o , sem a aposição de caracteres a M, e tem o mesmo comprimento que subcadeia especificador.

v) O número de subsequências de M é igual ao número de substring especificadores de P.

(ênfase adicionado).

Isso é muito prolixo, então vamos dividi-la. Incisos II e III referem-se ao _ wildcards e %, respectivamente. Se P não contém quaisquer caracteres especiais, então só iv item se aplica. Este é o caso de interesse colocado pelo OP.

Neste caso, ele compara cada "substring" (caracteres individuais) em M uns contra os substring em P usando o agrupamento atual.

Conclusões

A linha inferior é que quando se compara cordas, = compara a seqüência inteira, enquanto LIKE compara um carácter de cada vez. Ambas as comparações usar o agrupamento atual. Esta diferença conduz a resultados diferentes, em alguns casos, como evidenciado no primeiro exemplo neste post.

Qual deles você deve usar? Ninguém pode dizer-lhe que - você precisa usar o que é correto para o seu caso de uso. Não prematuramente otimizar mudando operadores de comparação.

Outras dicas

A é igual (=) operador é um "operador de comparação compara dois valores para a igualdade." Em outras palavras, em uma instrução SQL, não vai retornar true a menos que ambos os lados da equação são iguais. Por exemplo:

SELECT * FROM Store WHERE Quantity = 200;

O operador LIKE "implementa uma comparação padrão de jogo" que as tentativas para corresponder "um valor de string contra uma cadeia padrão contendo personagens selvagens-card." Por exemplo:

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

COMO é geralmente usado apenas com cordas e equals (eu acredito) é mais rápido. O operador equals trata caracteres curinga como caracteres literais. A diferença nos resultados retornados são os seguintes:

SELECT * FROM Employees WHERE Name = 'Chris';

E

SELECT * FROM Employees WHERE Name LIKE 'Chris';

Se voltar o mesmo resultado, embora usando COMO seria geralmente levam mais tempo como uma correspondência de padrão. No entanto,

SELECT * FROM Employees WHERE Name = 'Chris%';

E

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

Será que retornar resultados diferentes, onde o uso de "=" resulta em apenas resultados com "Chris%" a serem devolvidos e o operador LIKE retornará nada começando com "Chris".

Espero que ajude. Algumas informações de bom pode ser encontrada aqui .

LIKE e = são diferentes. LIKE é o que você usaria em uma consulta de pesquisa. Ele também permite wildcards como _ (simples curinga de caracteres) e % (wildcard multi-personagem).

= deve ser usado se você quiser correspondências exatas e será mais rápido.

Este site explica LIKE

Este é um copy / paste de outra resposta da mina para questão SQL 'como' vs '=' desempenho :

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

Ao usar um como em um índice como abaixo (sem curingas), que demorou cerca de 30 segundos:

where login like '12345678'

usando 'explicar' eu recebo:

enter descrição da imagem aqui

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

where login ='12345678'

Usando 'explicar' eu recebo:

enter descrição da imagem aqui

Como você pode ver, o like cancelada completamente a busca de índice, por isso consulta levou 300 vezes mais tempo.

Uma diferença - além da possibilidade de usar curingas com gosto - está em espaços à direita: O espaço = ignora operador de fuga, mas como não

.

Depende do sistema de banco de dados.

Geralmente sem caracteres especiais, sim, = E como são os mesmos.

Alguns sistemas de banco de dados, no entanto, pode tratar configurações de agrupamento de forma diferente com os diferentes operadores.

Por exemplo, em comparação com MySQL = em cordas é sempre maiúsculas e minúsculas por padrão, portanto LIKE sem caracteres especiais é o mesmo. Em como algumas outras das RDBMS é case-insensitive, enquanto = não é.

Para este exemplo, é um dado adquirido que varcharcol não contém '' e não têm nenhuma célula vazia contra esta coluna

select * from some_table where varcharCol = ''
select * from some_table where varcharCol like ''

A primeira delas resulta em saída de 0 linha, enquanto o segundo, mostra toda a lista. = É estritamente match-caso, enquanto como age como um filtro. se o filtro não tem critérios, todos os dados é válido.

como -. Pela virtude de sua finalidade funciona um pouco mais lento e se destina ao uso com varchar e dados semelhantes

Se você procurar por uma correspondência exata, você pode usar ambos, = e LIKE.

Usando o "=" é um pouco mais rápido, neste caso (à procura de uma correspondência exata) - você pode verificar isso sozinho por ter a mesma consulta duas vezes em SQL Server Management Studio, uma vez que o uso de "=", uma vez usando "COMO " e, em seguida, usando a 'consulta' / 'Incluir plano de execução real'.

Executar as duas consultas e você deve ver os seus resultados duas vezes, mais os dois planos de execução reais. No meu caso, eles foram dividida 50% vs. 50%, mas o "=" plano de execução tem um "custo sub estimado" menor (exibido quando você passa o mouse sobre o mais à esquerda caixa "SELECT") - mas novamente, é realmente não uma enorme diferença.

Mas quando você começar a pesquisar com curingas em sua expressão LIKE, o desempenho da pesquisa vai dimish. Pesquisar "como Mill%" ainda pode ser bastante rápida - SQL Server pode utilizar um índice nessa coluna, se houver. Procurando "COMO% expressão%" é terrivelmente lento, uma vez que a única maneira de SQL Server pode satisfazer esta pesquisa é fazendo uma varredura completa da tabela. Portanto, tenha cuidado com o seu gostar!

Marc

Usando = Evita wildcards e conflitos caracteres especiais na string quando você constrói a consulta em tempo de execução.

Isto torna a vida do programador mais fácil por não ter de escapar de todas caracteres curinga especiais que se possa imiscuir na cláusula LIKE e não produzir o resultado pretendido. Afinal, = é o cenário de caso de uso de 99%, que seria uma dor de ter de escapar deles de cada vez.

rolos olhos no '90s

Eu também suspeito que é um pouco mais lento, mas eu duvido que é significativo se não há curingas no padrão.

Para resolver a pergunta original em relação ao desempenho, ele se resume a a utilização do índice . Quando uma simples verificação de tabela ocorre, "como" e "=" são idênticas . Quando os índices estão envolvidos, ele depende em como a cláusula LIKE é formado. Mais especificamente, qual é a localização dos curinga (s)?


Considere o seguinte:

CREATE TABLE test(
    txt_col  varchar(10) NOT NULL
)
go

insert test (txt_col)
select CONVERT(varchar(10), row_number() over (order by (select 1))) r
  from master..spt_values a, master..spt_values b
go

CREATE INDEX IX_test_data 
    ON test (txt_col);
go 

--Turn on Show Execution Plan
set statistics io on

--A LIKE Clause with a wildcard at the beginning
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '%10000'
--Results in
--Table 'test'. Scan count 3, logical reads 15404, physical reads 2, read-ahead reads 15416, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index SCAN is 85% of Query Cost

--A LIKE Clause with a wildcard in the middle
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '1%99'
--Results in
--Table 'test'. Scan count 1, logical reads 3023, physical reads 3, read-ahead reads 3018, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost for test data, but it may result in a Table Scan depending on table size/structure

--A LIKE Clause with no wildcards
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO

--an "=" clause = does Index Seek same as above
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col = '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO


DROP TABLE test

Pode haver diferença também insignificante na criação do plano de consulta ao usar "=" vs "LIKE".

Além dos wildcards, a diferença entre = E LIKE dependerá tanto o tipo de servidor SQL e sobre o tipo de coluna.

Veja este exemplo:

CREATE TABLE testtable (
  varchar_name VARCHAR(10),
  char_name CHAR(10),
  val INTEGER
);

INSERT INTO testtable(varchar_name, char_name, val)
    VALUES ('A', 'A', 10), ('B', 'B', 20);

SELECT 'VarChar Eq Without Space', val FROM testtable WHERE varchar_name='A'
UNION ALL
SELECT 'VarChar Eq With Space', val FROM testtable WHERE varchar_name='A '
UNION ALL
SELECT 'VarChar Like Without Space', val FROM testtable WHERE varchar_name LIKE 'A'
UNION ALL
SELECT 'VarChar Like Space', val FROM testtable WHERE varchar_name LIKE 'A '
UNION ALL
SELECT 'Char Eq Without Space', val FROM testtable WHERE char_name='A'
UNION ALL
SELECT 'Char Eq With Space', val FROM testtable WHERE char_name='A '
UNION ALL
SELECT 'Char Like Without Space', val FROM testtable WHERE char_name LIKE 'A'
UNION ALL
SELECT 'Char Like With Space', val FROM testtable WHERE char_name LIKE 'A '
  • Usando MS SQL Server 2012 , os espaços à direita será ignorado em a comparação, excepto com LIKE quando o tipo de coluna é VARCHAR.

  • Usando MySQL 5.5 , os espaços à direita será ignorada para =, mas não para LIKE, ambos com CHAR e VARCHAR.

  • Usando PostgreSQL 9.1 , os espaços são significativos tanto com = e LIKE usando VARCHAR, mas não com CHAR (ver documentação ).

    O comportamento com LIKE também difere com CHAR.

    Usando os mesmos dados como acima, usando um CAST explícita no nome da coluna também faz a diferença :

    SELECT 'CAST none', val FROM testtable WHERE char_name LIKE 'A'
    UNION ALL
    SELECT 'CAST both', val FROM testtable WHERE
        CAST(char_name AS CHAR) LIKE CAST('A' AS CHAR)
    UNION ALL
    SELECT 'CAST col', val FROM testtable WHERE CAST(char_name AS CHAR) LIKE 'A'
    UNION ALL
    SELECT 'CAST value', val FROM testtable WHERE char_name LIKE CAST('A' AS CHAR)
    

    Isso só retorna linhas para "lançar tanto" e "lançar col".

O COMO palavra-chave, sem dúvida, vem com um "desempenho preço-tag" anexado. Dito isto, se você tem um campo de entrada que poderia incluir caracteres curinga para ser usado em sua consulta, eu recomendo usar COMO apenas se a entrada contém um dos wild cards. Caso contrário, use a igual padrão para comparação.

Com os melhores cumprimentos ...

Realmente tudo se resume ao que você quer a consulta para fazer. Se você quer dizer uma correspondência exata então usar =. Se você quer dizer uma partida fuzzier, então use LIKE. Dizer o que você quer dizer é geralmente uma boa política com o código.

Na Oracle, um ‘como’ sem curingas retornará o mesmo resultado como uma ‘iguais’, mas poderia exigir processamento adicional. De acordo com Tom Kyte , a Oracle vai tratar um 'como' sem curingas como um 'igual' ao usar literais, mas não quando usando variáveis ??de ligação.

= e LIKE não é o mesmo;

  1. = corresponde a seqüência exata
  2. LIKE corresponde a uma string que pode conter wildcards (%)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top