Esta pregunta bordea lo que me pregunto, pero las respuestas no lo abordan exactamente.
Parecería que, en general, '=' es más rápido que 'me gusta' cuando se utilizan comodines. Esta parece ser la sabiduría convencional. Sin embargo, supongamos que tengo una columna que contiene un número limitado de diferentes identificadores varchar fijos, codificados, y quiero seleccionar todas las filas que coincidan con uno de ellos:
select * from table where value like 'abc%'
y
select * from table where value = 'abcdefghijklmn'
'Me gusta' solo debería necesitar probar los primeros tres caracteres para encontrar una coincidencia, mientras que '=' debe comparar toda la cadena. En este caso, me parecería que "me gusta" tendría una ventaja, en igualdad de condiciones.
Esto está pensado como una pregunta académica general, por lo que no debería importar qué base de datos, pero surgió con SQL Server 2005.
fuente
value
está indexada o no . Si es así, entonces=
es una búsqueda simple sin necesidad de escanear la tabla y le quitará los pantalones a cualquierLIKE
declaración que le arroje.LIKE
con un comodín al final es SARGable y, por lo tanto, realizará una búsqueda de rango en un índice, sin escaneo de tabla a la vista. Esa búsqueda de rango puede competir muy fácilmente con una=
declaración y, en muchos casos (como si todas las filas satisfactorias estuvieran en una página, una condición no poco probable) podría tener exactamente el mismo rendimiento, lo que implica el mismo número de lecturas.Respuestas:
Ver https://web.archive.org/web/20150209022016/http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx
Cita desde allí:
fuente
Es una diferencia medible.
Ejecute lo siguiente:
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)
Entonces:
SET SHOWPLAN_XML ON
Entonces:
SELECT * FROM #TempTester WHERE value LIKE 'abc%' SELECT * FROM #TempTester WHERE value = 'abcdefghij'
El plan de ejecución resultante le muestra que el costo de la primera operación, la
LIKE
comparación, es aproximadamente 10 veces más caro que la=
comparación.Si puede utilizar una
=
comparación, hágalo.fuente
19.95
costos de SQL Server en 19 búsquedas clave adicionales que nunca se materializan en la actualidad (incluso en el plan de ejecución real , los costos que se muestran se basan en el costo estimado del subárbol )LIKE
, 203ms para=
. Espero que si ejecutara más pruebas y tomara promedios precisos, no habría una diferencia real entre #temp y la tabla real.También debe tener en cuenta que, al usar
like
, algunos tipos de SQL ignorarán los índices y eso matará el rendimiento. Esto es especialmente cierto si no usa el patrón "comienza con" como en su ejemplo.Realmente debería mirar el plan de ejecución de la consulta y ver qué está haciendo, adivinar lo menos posible.
Dicho esto, el patrón "comienza con" puede y está optimizado en el servidor SQL. Se va a utilizar el índice de la tabla. EF 4.0 cambió a
like
paraStartsWith
por esta misma razón.fuente
Si
value
no está indexado, ambos dan como resultado un escaneo de tabla. La diferencia de rendimiento en este escenario será insignificante.Si
value
está indexado, como señala Daniel en su comentario,=
dará como resultado una búsqueda de índice que es el rendimiento O (log N). El LIKE (lo más probable, dependiendo de qué tan selectivo sea) dará como resultado un escaneo parcial del índice>= 'abc'
y< 'abd'
requerirá más esfuerzo que el=
.Tenga en cuenta que estoy hablando de SQL Server aquí, no todos los DBMS serán buenos con LIKE.
fuente
=
caso como ellike '...%'
caso se comportan de la misma manera si sql reconoce el patrón (y lo hace), porque en ambos casos los subárboles se eligen en base a relaciones de comparación.'abd'
se alcanza el punto final .Estás haciendo la pregunta incorrecta. En las bases de datos no es el rendimiento del operador lo que importa, es siempre la SARGability de la expresión y la cobertura de la consulta general. El desempeño del propio operador es en gran parte irrelevante.
Entonces, ¿cómo comparar
LIKE
y=
comparar en términos de SARGability?LIKE
, cuando se usa con una expresión que no comienza con una constante (por ejemplo, cuando se usaLIKE '%something'
), por definición no es SARGabale. ¿Pero eso hace=
oLIKE 'something%'
SARGable? No. Al igual que con cualquier pregunta sobre el rendimiento de SQL, la respuesta no está en la consulta del texto, sino en el esquema implementado. Estas expresiones pueden ser SARGable si existe un índice para satisfacerlas.Entonces, a decir verdad, hay pequeñas diferencias entre
=
yLIKE
. Pero preguntar si un operador u otro operador es "más rápido" en SQL es como preguntar "¿Qué va más rápido, un coche rojo o un coche azul?". Debería hacer preguntas sobre el tamaño del motor y el peso del vehículo, no sobre el color ... Para abordar las preguntas sobre la optimización de tablas relacionales, el lugar para buscar son sus índices y sus expresiones en la cláusula WHERE (y otras cláusulas, pero generalmente comienza con el DÓNDE).fuente
Un ejemplo personal usando mysql 5.5: tenía una combinación interna entre 2 tablas, una de 3 millones de filas y una de 10 mil filas.
Al usar un me gusta en un índice como se muestra a continuación (sin comodines), tomó aproximadamente 30 segundos:
usando 'explicar' obtengo:
Al usar un '=' en la misma consulta, tomó alrededor de 0.1 segundos:
Usando 'explicar' obtengo:
Como puede ver, la
like
búsqueda de índice canceló por completo, por lo que la consulta tomó 300 veces más tiempo.fuente
Quizás esté buscando una búsqueda de texto completo .
fuente
Lo primero es lo primero ,
no siempre son iguales
select 'Hello' from dual where 'Hello ' like 'Hello'; select 'Hello' from dual where 'Hello ' = 'Hello';
cuando las cosas no siempre son iguales, hablar de su desempeño no es tan relevante.
Si está trabajando con cadenas y solo variables de caracteres, puede hablar sobre el rendimiento. Pero no use like y "=" como si fueran generalmente intercambiables.
Como habrá visto en muchas publicaciones (anteriores y otras preguntas), en los casos en que son iguales, el rendimiento de Me gusta es más lento debido a la coincidencia de patrones (intercalación)
fuente
'Hello '
es unVARCHAR
(predeterminado), está en lo correcto, pero si es un,CHAR
no lo está. Transfiéralo a ayCHAR(7)
ambos devuelven verdadero. Además, ¿qué diablos estás haciendo donde noTRIM
estás usando tus varchars? (nota: este es al menos el caso enSQL Server 2008r2
)