Pregunta

Al usar SQL, ¿hay algún beneficio al usar = en un WHERE cláusula en lugar de LIKE?

Sin ningún operador especial, LIKE y = son iguales no?

¿Fue útil?

Solución

Diferentes operadores

LIKE y = son diferentes operadores. La mayoría de las respuestas aquí se centran en el soporte de comodines, que no es la única diferencia entre estos operadores!

= es un operador de comparación que opera en números y cadenas. Al comparar cadenas, el operador de comparación compara cadenas enteras .

LIKE es un operador de cadena que compara carácter por carácter .

Para complicar las cosas, ambos operadores utilizan una que puede tener efectos importantes sobre el resultado de la comparación.

Ejemplo de motivación

El primer identificar un ejemplo en el que estos operadores producen resultados diferentes, obviamente, Let. Permítanme citar del manual de MySQL:

  

Por el estándar SQL, COMO, se adapta en función de cada carácter, por lo que puede producir resultados diferentes del operador de comparación =:

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 |
+--------------------------------------+

Tenga en cuenta que esta página del manual de MySQL se llama Funciones de comparación de cadenas , y = no se discute, lo que implica que = no es estrictamente una función de comparación de cadenas.

¿Cómo funciona =?

El SQL estándar § 8.2 describe cómo se compara = cadenas:

  

La comparación de las dos cadenas de caracteres se determina de la siguiente manera:

     

a) Si la longitud en caracteres de X no es igual a la longitud   en caracteres de Y, a continuación, la cadena más corta es efectivamente   reemplazado, a efectos de comparación, con una copia de   sí que se ha extendido a la longitud de la más larga   cadena mediante la concatenación a la derecha de uno o más de la almohadilla   personajes, cuando se elija el carácter de relleno basado en CS. Si   CS tiene el atributo PAD NO, entonces el carácter de relleno es una   el carácter dependiente de la implementación diferente de cualquier   carácter en el conjunto de caracteres de X e Y que coteja menos   que cualquier cadena de conformidad con las CS. De lo contrario, el carácter de relleno es una   .

     

b) El resultado de la comparación de X e Y es dada por el   secuencia de clasificación CS.

     

c) En función de la secuencia de clasificación, dos cadenas puede   comparar como igual, incluso si son de diferentes longitudes o   contener diferentes secuencias de caracteres. Cuando las operaciones   MAX, MIN, DISTINCT, las referencias a una columna de agrupación, y la   UNION, EXCEPT e INTERSECT se refieren al carácter   cuerdas, el valor específico seleccionado por estas operaciones de   un conjunto de tales valores iguales es dependiente de la implementación.

(Énfasis añadido).

¿Qué significa esto? Esto significa que al comparar cadenas, el operador = es sólo un envoltorio fino alrededor de la colación actual. A colación es una biblioteca que tiene varias reglas para comparar cadenas. Aquí está un ejemplo de una colación binaria 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 cotejo particular, pasa a comparar byte por byte (por eso se llama "binario" - no da ningún significado especial para cuerdas). Otros colaciones pueden proporcionar comparaciones más avanzadas.

Por ejemplo, aquí es una UTF 8 intercalación que soporta comparaciones entre mayúsculas y minúsculas. El código es demasiado largo para pegar aquí, pero ir a ese enlace y leer el cuerpo de my_strnncollsp_utf8mb4(). Esta intercalación puede procesar múltiples bytes a la vez y se puede aplicar varias transformaciones (como caso comparación insensible). El operador = está completamente abstraídode los caprichos de la intercalación.

¿Cómo funciona LIKE?

El SQL estándar § 8.5 describe cómo se compara LIKE cadenas:

  

La

     

M LIKE P

     

es cierto si existe una partición de M en subcadenas   tal que:

     

i) una subcadena de M es una secuencia de 0 o más contiguos    s de M y cada carácter <   representación> de M es parte de exactamente una subcadena.

     

ii) Si la subcadena especificador i-ésimo de P es un arbitraria   especificador de carácter, la subcadena i de M es un solo   .

     

iii) Si la subcadena especificador i-ésimo de P es una cadena arbitraria   especificador, a continuación, la subcadena i-ésimo de M es cualquier secuencia de   0 o más s.

     

iv) Si la subcadena especificador i-ésimo de P no es ni una   especificador de carácter arbitrario, ni un especificador de cadena arbitraria,   entonces la subcadena i-ésimo de M es igual a la subcadena   especificador de acuerdo con el orden de clasificación de   el , sin la Anexión de   caracteres a M, y tiene la misma longitud que la subcadena   especificador.

     

v) El número de subcadenas de M es igual al número de   subcadena especificadores de P.

(Énfasis añadido).

Esto es muy prolijo, así que vamos a romper. Artículos II y III se refieren a la _ comodines y %, respectivamente. Si P no contiene comodines, a continuación, se aplica únicamente la fracción IV. Este es el caso de los intereses que plantea la OP.

En este caso, se compara cada "subcadena" (caracteres individuales) en M contra cada subcadena en P usando la intercalación actual.

Conclusiones

La conclusión es que al comparar cadenas, = compara la cadena completa, mientras que LIKE compara un carácter a la vez. Ambas comparaciones usan la intercalación actual. Esta diferencia conduce a resultados diferentes en algunos casos, como se evidencia en el primer ejemplo en este post.

¿Cuál debería utilizar? Nadie puede decir que - es necesario utilizar el que sea correcto para el caso de uso. No prematuramente optimizar cambiando operadores de comparación.

Otros consejos

Las igual (=) operador es un "operador de comparación compara dos valores para la igualdad." En otras palabras, en una sentencia SQL, no retornará cierto a menos que ambos lados de la ecuación son iguales. Por ejemplo:

SELECT * FROM Store WHERE Quantity = 200;

El operador LIKE "implementa un patrón de comparación partido" que intenta hacer coincidir "un valor de cadena contra una cadena de patrón que contiene caracteres comodín." Por ejemplo:

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

LIKE se utiliza generalmente sólo con cuerdas y equals (creo) es más rápido. El operador es igual golosinas caracteres comodín como caracteres literales. La diferencia de resultados devueltos son los siguientes:

SELECT * FROM Employees WHERE Name = 'Chris';

y

SELECT * FROM Employees WHERE Name LIKE 'Chris';

volvería el mismo resultado, aunque utilizando como sería en general tomar más tiempo ya que es una coincidencia de patrón. Sin embargo,

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

y

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

volvería resultados diferentes, donde el uso de "=" Resultados en sólo resultados con "Chris%" su restitución, cuando el operador LIKE volverá cualquier cosa que empiece con "Chris".

Espero que ayude. Buena información se puede encontrar aquí .

LIKE y = son diferentes. LIKE es la que se uso en una consulta de búsqueda. También permite comodines como _ (simple carácter comodín) y % (comodín de un carácter).

= se debe utilizar si desea coincidencias exactas y que será más rápido.

Este sitio explica LIKE

Este es un copiar / pegar de otra respuesta para la pregunta de la mina 'como' vs '=' rendimiento:

Un ejemplo personal usando MySQL 5.5: Tenía una unión interna entre 2 mesas, una de 3 millones de filas y uno de 10 mil filas

.

Cuando se utiliza una como en un índice de la siguiente manera (no hay comodines), que tomó cerca de 30 segundos:

where login like '12345678'

usando 'explicar' me sale:

introducir descripción de la imagen aquí

Cuando se utiliza un '=' en la misma consulta, se tomaron aproximadamente 0,1 segundos:

where login ='12345678'

El uso de 'explicar' me sale:

introducir descripción de la imagen aquí

Como se puede ver, el like anule por completo la búsqueda de índice, por lo Consulta tomó 300 veces más tiempo.

.

Una diferencia - aparte de la posibilidad de utilizar comodines con LIKE - se encuentra en los espacios finales: El operador = ignora arrastra el espacio, pero como no lo hace

Depende del sistema de base de datos.

En general, sin caracteres especiales, sí, = y similar son los mismos.

Algunos sistemas de bases de datos, sin embargo, puede tratar la configuración de intercalación de manera diferente con los diferentes operadores.

Por ejemplo, en comparación con MySQL = en las cadenas es siempre entre mayúsculas y minúsculas de forma predeterminada, por lo que quieran sin caracteres especiales es el mismo. En alguna otra como la de RDBMS es sensible a las mayúsculas, mientras que = no lo es.

En este ejemplo se da por supuesto que varcharcol no contiene '' y no tienen ninguna celda vacía contra esta columna

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

Los primeros uno Resultados en 0 de salida de fila, mientras que el segundo muestra toda la lista. = Estrictamente al partido como caso mientras actúa como un filtro. Si el filtro no tiene ningún criterio, todos los datos son válidos.

Al igual que -. Por la virtud de su propósito funciona un poco más lento y está diseñado para su uso con los datos varchar y similares

Si busca una coincidencia exacta, se puede utilizar tanto, = y similares.

El uso de "=" es un poquito más rápido en este caso (la búsqueda de una coincidencia exacta) - se puede verificar esto haciendo que la misma consulta dos veces en SQL Server Management Studio, una vez que el uso de "=", una vez que el uso de "COMO " y, a continuación, utilizando la 'consulta' / 'Incluir plan de ejecución real'.

Ejecutar las dos consultas y debería ver los resultados de dos veces, además de los dos planes de ejecución reales. En mi caso, se dividieron 50% frente a 50%, pero el "=" plan de ejecución tiene un "costo estimado subárbol" más pequeño (que aparece cuando se pasa sobre el cuadro de "SELECT" más a la izquierda) - pero de nuevo, es realmente no hay una gran diferencia.

Sin embargo, cuando se inicia la búsqueda con comodines en su expresión como, el rendimiento de búsqueda se dimish. Buscar "COMO Molino%" todavía puede ser bastante rápido - SQL Server puede utilizar un índice en esa columna, si es que existe. Buscando "COMO% de expresión%" es terriblemente lento, ya que la única manera de SQL Server puede satisfacer esta búsqueda es haciendo un escaneo completo de tabla. Así que tenga cuidado con su gusto de!

Marc

El uso de comodines = evita conflictos y caracteres especiales en la cadena cuando se genera la consulta en tiempo de ejecución.

Esto hace que la vida del programador más fácil al no tener que todos los caracteres comodín especiales que se pueda inmiscuir en la cláusula LIKE y no producen el resultado deseado. Después de todo, = es el escenario de caso de uso 99%, sería un dolor de tener que escapar de ellos en todo momento.

Rodillos ojos en los años 90

También sospecho que es un poco más lento, pero dudo que sea significativo si no hay comodines en el patrón.

Para hacer frente a la pregunta original respecto al rendimiento, todo se reduce a utilización index . Cuando se produce un simple recorrido de tabla, "como" y "=" son idénticos . Cuando los índices están involucrados, es depende en cómo se forma la cláusula LIKE. Más específicamente, ¿cuál es la posición del comodín (s)?


Tenga en cuenta lo siguiente:

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

Puede haber también diferencias insignificantes en la creación del plan de consulta cuando se utiliza "=" vs "similares".

Además de los comodines, la diferencia entre = Y LIKE dependerá tanto del tipo de servidor SQL y del tipo de columna.

Tome este ejemplo:

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 '
  • Uso MS SQL Server 2012 , los espacios finales se tendrá en cuenta en la comparación, excepto con LIKE cuando el tipo de columna es VARCHAR.

  • Uso MySQL 5.5 , los espacios finales serán ignorados para =, pero no para LIKE, ambos con CHAR y VARCHAR.

  • PostgreSQL 9.1 , los espacios son significativos tanto con = y utilizando LIKE VARCHAR, pero no con CHAR (ver documentación ).

    El comportamiento con LIKE también difiere con CHAR.

    El uso de los mismos datos que la anterior, utilizando un CAST explícita sobre el nombre de la columna href="http://sqlfiddle.com/#!1/4b92d/1" también hace una diferencia :

    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)
    

    Esto sólo devuelve las filas de "REPARTO tanto" y "REPARTO col".

La palabra clave LIKE, sin duda, viene con un "rendimiento de precio de etiqueta" adjunto. Dicho esto, si usted tiene un campo de entrada que podrían potencialmente incluir caracteres comodín para ser utilizado en la consulta, yo recomendaría usar COMO sólo si la entrada contiene uno de los comodines. De lo contrario, utilice el igual estándar para comparación.

Saludos ...

En realidad todo se reduce a lo que usted desea que la consulta a hacer. Si se refiere a una correspondencia exacta a continuación, utilizar =. Si se refiere a un partido más difusa, a continuación, utilizar similares. Diciendo lo que quiere decir es por lo general una buena política con el código.

En Oracle, un ‘como’ sin comodines devolverá el mismo resultado que una ‘iguales’, pero podría requerir procesamiento adicional. De acuerdo con Tom Kyte , Oracle va a tratar un 'como' sin comodines como 'iguales' cuando se utiliza literales, pero no cuando se utilizan variables de enlace.

= y LIKE no es lo mismo;

  1. = coincide con la cadena exacta
  2. LIKE coincide con una cadena que puede contener comodines (%)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top