La mejor manera de probar si existe una fila en una tabla MySQL


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 compruebe si el total es distinto de cero o es mejor hacer una consulta como esta:

SELECT * FROM table1 WHERE ... LIMIT 1

Y comprobar si se devolvieron filas?

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

Author: OMG Ponies, 2009-11-04

12 answers

También puedes intentar usar

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

Por la documentación

Por un comentario a continuación:

SELECT EXISTS(SELECT 1 FROM table1 WHERE ...)
 398
Author: Chris Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-04 22:59:48

He hecho algunas investigaciones sobre este tema recientemente. La forma de implementarlo 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 de 1M. 37 entradas son iguales a 'algo':

  • SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1 con mysql_num_rows(): 0.039061069488525 s. (MÁS RÁPIDO)
  • SELECT count(*) as count FROM test WHERE text LIKE '%something% : 16.028197050095 s.
  • SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%') : 0,87045907974243 s.
  • SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1) : 0,044898986816406 s.

Pero ahora, con un campo BIGINT PK, solo una entrada es igual a '321321':

  • SELECT * FROM test2 WHERE id ='321321' LIMIT 1 con mysql_num_rows(): 0.0089840888977051 s.
  • SELECT count(*) as count FROM test2 WHERE id ='321321': 0,00033879280090332 s.
  • SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321'): 0.00023889541625977 s.
  • SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1): 0.00020313262939453 s. (MÁS RÁPIDO)
 142
Author: Laurent W.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-21 15:23:13

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)

Usando un alias:

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)
 20
Author: jaltek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-19 11:18:26

En mi investigación, puedo encontrar el resultado consiguiendo en la velocidad siguiente.

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) 
 6
Author: shihab mm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-15 06:32:30

Sugiere que no use {[0] } porque count siempre hace cargas adicionales para db use SELECT 1 y devuelve 1 si su registro allí, de lo contrario, devuelve null y puede manejarlo.

 4
Author: Fatih Karatana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-02 15:21:58

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

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

SELECT IFNULL(`id`, COUNT(*)) FROM WHERE ...
 2
Author: Zaxter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-22 06:50:37

Creo que vale la pena señalar, aunque se mencionó 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 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 cláusula LIMIT permite que el motor se detenga 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 para el motor, pero todavía escribiría el 1 para eliminar cualquier duda:

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

Puede tener sentido agregar el EXISTS wrapping is si requiere un retorno explícito cuando no hay filas coincidentes.

 2
Author: Arth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-19 14:56:24

Yo iría con COUNT(1). Es más rápido que COUNT(*) porque COUNT(*) pruebas para ver si al menos una columna en esa fila es != NULO. No necesita eso, especialmente porque ya tiene una condición en su lugar (la cláusula WHERE). COUNT(1) en su lugar prueba la validez de 1, que siempre es válida y toma mucho menos tiempo para probar.

 0
Author: Felix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-04 21:15:33

A RECUENTO la consulta es más rápida, aunque tal vez no notablemente, pero en cuanto a obtener el resultado deseado, ambos deberían ser suficientes.

 0
Author: jaywon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-17 17:39:47

Para tablas que no son InnoDB también puede usar las tablas de esquema de información:

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

 -1
Author: davek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-04 21:12:33

O puede insertar una parte sql sin procesar en las condiciones así que tengo 'conditions' = > array('Member.id NO ESTÁ (SELECCIONE Membresía.member_id DE memberships COMO Membership)')

 -1
Author: user4193303,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-29 09:18:01

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

 -2
Author: Arthur Reutenauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-04 21:01:53