Pregunta

Estoy tratando de averiguar si existe una fila en una tabla. El uso de MySQL, es mejor hacer una consulta como la siguiente:

SELECT COUNT(*) AS total FROM table1 WHERE ...

y comprobar para ver si el total no es cero o es mejor hacer una consulta como la siguiente:

SELECT * FROM table1 WHERE ... LIMIT 1

y comprobar para ver si se devuelven las filas?

En ambos consultas, la cláusula WHERE utiliza un índice.

¿Fue útil?

Solución

También puede probar EXISTS:

SELECT EXISTS(SELECT * FROM table1 WHERE ...)

la documentación , puede SELECT nada.

  

Tradicionalmente, una subconsulta EXISTS comienza con SELECT *, pero podría   comenzar con SELECT o SELECT 5 column1 o nada en absoluto. MySQL   hace caso omiso de la lista SELECT en tales subconsultas, por lo que no hace ninguna diferencia.

Otros consejos

He hecho algunas investigaciones sobre este tema recientemente. La manera de poner en práctica lo que tiene que ser diferente si el campo es un campo de texto, un campo no único.

He hecho algunas pruebas con un campo de texto. Teniendo en cuenta el hecho de que tenemos una tabla con entradas 1M. 37 entradas son iguales a 'algo':

  • SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1 con mysql_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, sólo una entrada es igual a '321321':

  • SELECT * FROM test2 WHERE id ='321321' LIMIT 1 con mysql_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)

Un breve ejemplo de la respuesta de @ ChrisThompson

Ejemplo:

mysql> SELECT * FROM table_1;
+----+--------+
| id | col1   |
+----+--------+
|  1 | foo    |
|  2 | bar    |
|  3 | foobar |
+----+--------+
3 rows in set (0.00 sec)

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1);
+--------------------------------------------+
| EXISTS(SELECT 1 FROM table_1 WHERE id = 1) |
+--------------------------------------------+
|                                          1 |
+--------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 9);
+--------------------------------------------+
| EXISTS(SELECT 1 FROM table_1 WHERE id = 9) |
+--------------------------------------------+
|                                          0 |
+--------------------------------------------+
1 row in set (0.00 sec)

El uso de un alias:

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)

En mi investigación, puedo encontrar el resultado subirse siguiente velocidad.

select * from table where condition=value
(1 total, Query took 0.0052 sec)

select exists(select * from table where condition=value)
(1 total, Query took 0.0008 sec)

select count(*) from table where condition=value limit 1) 
(1 total, Query took 0.0007 sec)

select exists(select * from table where condition=value limit 1)
(1 total, Query took 0.0006 sec) 

Creo que vale la pena señalar, aunque se refirió a en los comentarios, que en esta situación:

SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1

es superior a:

SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1

Esto se debe a que la primera consulta puede ser satisfecha por el índice, mientras que el segundo requiere una fila mirar hacia arriba (a menos que, posiblemente, todas las columnas de la tabla están en el índice utilizado).

Adición de la cláusula LIMIT permite que el motor se detiene después de encontrar cualquier fila.

La primera consulta debe ser comparable a:

SELECT EXISTS(SELECT * FROM my_table WHERE *indexed_condition*)

que envía las mismas señales al motor (1 / * no hace ninguna diferencia en este caso), pero todavía me gustaría escribir el 1 de reforzar el hábito cuando se utiliza EXISTS:

SELECT EXISTS(SELECT 1 FROM my_table WHERE *indexed_condition*)

Tal vez tenga sentido para agregar la envoltura EXISTS si necesita rendimiento explícito cuando no hay filas coinciden.

Sugiere que no utilice Count porque siempre hace recuento de cargas adicionales para el uso db SELECT 1 y vuelve 1 si su historial de ahí lo contrario, devuelve un valor nulo y se puede manejar la situación.

A veces es muy útil para obtener la clave principal incremento automático (id) de la fila si existe y 0 si no lo hace.

Así es como esto se puede hacer en una sola consulta:

SELECT IFNULL(`id`, COUNT(*)) FROM WHERE ...

Me gustaría ir con COUNT(1). Es más rápido que COUNT(*) porque las pruebas COUNT(*) para ver si al menos una columna de esa fila es! = NULL. No es necesario que, sobre todo porque ya tiene una condición en su lugar (la cláusula WHERE). COUNT(1) lugar a prueba la validez de 1, que es siempre válido y lleva mucho menos tiempo para probar.

A COUNT consulta es más rápido, aunque quizás no perceptiblemente, pero en cuanto a conseguir el resultado deseado, ambos deben ser suficientes.

Para las tablas no InnoDB también se podría utilizar las tablas del esquema de información:

http://dev.mysql.com/doc /refman/5.1/en/tables-table.html

O puede insertar parte sql prima a las condiciones así que tengo = 'condiciones'> array ( 'Member.id NO EN (SELECCIONAR Membership.member_id DE pertenencias como la pertenencia)')

COUNT(*) están optimizados en MySQL, por lo que la consulta anterior es probable que sea más rápido, en términos generales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top