Estoy tratando de averiguar si existe una fila en una tabla. Usando MySQL, ¿es mejor hacer una consulta como esta?
SELECT COUNT(*) AS total FROM table1 WHERE ...
y verifique si el total no es cero o es mejor hacer una consulta como esta:
SELECT * FROM table1 WHERE ... LIMIT 1
y verifica si alguna fila fue devuelta?
En ambas consultas, la cláusula WHERE usa un índice.
sql
mysql
performance
exists
Bernard Chen
fuente
fuente
...EXISTS( SELECT 1/0 FROM someothertable)
. Para SQL Server y Oracle: no hace ninguna diferencia usar *, 1 o NULL porque EXISTS solo prueba un valor booleano basado en 1+ de la coincidencia de criterios WHERE.SELECT 1 FROM table1 WHERE col = $var LIMIT 1
es más rápida que su consulta. Entonces, ¿cuál es la ventaja de su consulta?He realizado algunas investigaciones sobre este tema recientemente. La forma de implementarlo debe ser diferente si el campo es un campo TEXTO, un campo no único.
He realizado algunas pruebas con un campo TEXTO. Considerando el hecho de que tenemos una tabla con 1M de entradas. 37 entradas son iguales a 'algo':
SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1
conmysql_num_rows()
: 0.039061069488525s. (MÁS RÁPIDO)SELECT count(*) as count FROM test WHERE text LIKE '%something%
: 16.028197050095s.SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%')
: 0.87045907974243s.SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1)
: 0.044898986816406s.Pero ahora, con un campo BIGINT PK, solo una entrada es igual a '321321':
SELECT * FROM test2 WHERE id ='321321' LIMIT 1
conmysql_num_rows()
: 0.0089840888977051s.SELECT count(*) as count FROM test2 WHERE id ='321321'
: 0.00033879280090332s.SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321')
: 0.00023889541625977s.SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1)
: 0.00020313262939453s. (MÁS RÁPIDO)fuente
SELECT 1 FROM test WHERE texte LIKE '%something%' LIMIT 1
select 1 ... limit 1
, es inútil rodearlo con select existeSELECT 1 FROM test WHERE ...
, sinSELECT EXISTS
rodeos. Presumiblemente es un cabello más rápido de esa manera.Un breve ejemplo de la respuesta de @ ChrisThompson
Ejemplo:
Usando un alias:
fuente
En mi investigación, puedo encontrar el resultado en la siguiente velocidad.
fuente
Creo que vale la pena señalar, aunque se mencionó en los comentarios, que en esta situación:
Es superior a:
Esto se debe a que el índice puede satisfacer la primera consulta, mientras que la segunda requiere una búsqueda de fila (a menos que posiblemente todas las columnas de la tabla estén en el índice utilizado).
Agregar la
LIMIT
cláusula permite que el motor se detenga después de encontrar cualquier fila.La primera consulta debe ser comparable a:
Lo que envía las mismas señales al motor (1 / * no hace ninguna diferencia aquí), pero aún escribiría el 1 para reforzar el hábito al usar
EXISTS
:Puede tener sentido agregar el
EXISTS
ajuste si necesita un retorno explícito cuando no coinciden las filas.fuente
Sugiero que no lo use
Count
porque count siempre hace cargas adicionales para el uso de dbSELECT 1
y devuelve 1 si su registro allí mismo, de lo contrario, devuelve nulo y puede manejarlo.fuente
Una consulta COUNT es más rápida, aunque tal vez no sea notable, pero en lo que respecta a obtener el resultado deseado, ambas deberían ser suficientes.
fuente
A veces es bastante útil obtener la clave primaria de incremento automático (
id
) de la fila si existe y0
si no.Así es como se puede hacer esto en una sola consulta:
fuente
IFNULL(id, 0)
aquí en lugar delCOUNT(*)
?Para las tablas que no son de InnoDB, también puede usar las tablas de esquema de información:
http://dev.mysql.com/doc/refman/5.1/en/tables-table.html
fuente
Me gustaría ir con
COUNT(1)
. Es más rápido queCOUNT(*)
porque lasCOUNT(*)
pruebas para ver si al menos una columna en esa fila es! = NULL. No necesita eso, especialmente porque ya tiene una condición (laWHERE
cláusula).COUNT(1)
en cambio prueba la validez de1
, que siempre es válida y lleva mucho menos tiempo probarla.fuente
O puede insertar una parte sql sin procesar en las condiciones para que tenga 'condiciones' => array ('Member.id NOT IN (SELECCIONE Membership.member_id FROM membresías AS Membership)')
fuente
COUNT(*)
están optimizados en MySQL, por lo que es probable que la consulta anterior sea más rápida, en general.fuente