Najlepszy sposób na sprawdzenie, czy wiersz istnieje w tabeli MySQL

Próbuję dowiedzieć się, czy wiersz istnieje w tabeli. Używając MySQL, czy lepiej zrobić takie zapytanie:

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

I sprawdź, czy suma jest niezerowa, czy lepiej zrobić takie zapytanie:

SELECT * FROM table1 WHERE ... LIMIT 1

I sprawdzić, czy wiersze zostały zwrócone?

W obu zapytaniach klauzula WHERE Używa indeksu.

Author: OMG Ponies, 2009-11-04

12 answers

Możesz również spróbować użyć

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

Per dokumentacja

Za komentarz poniżej:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-04 22:59:48

Przeprowadziłem ostatnio kilka badań na ten temat. Sposób jego implementacji musi być inny, jeśli pole jest polem tekstowym, nie unikalnym polem.

Zrobiłem kilka testów z polem tekstowym. Biorąc pod uwagę fakt, że mamy tabelę z wpisami 1M. 37 wpisów jest równe 'coś':

  • SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1 z mysql_num_rows() : 0.039061069488525 s. (szybciej)
  • 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.

Ale teraz, z dużym polem PK, tylko jeden wpis jest równy '321321':

  • SELECT * FROM test2 WHERE id ='321321' LIMIT 1 z 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. (szybciej)
 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-21 15:23:13

[[2]} krótki przykład odpowiedzi @ ChrisThompson

Przykład:

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)

Użycie aliasu:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-19 11:18:26

W moich badaniach, mogę znaleźć wynik coraz na następujące prędkości.

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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 06:32:30

Sugeruję nie używać Count ponieważ count zawsze powoduje dodatkowe obciążenia dla db use SELECT 1 i zwraca 1 Jeśli twój rekord tam, w przeciwnym razie zwróci null i możesz go obsłużyć.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-02 15:21:58

Czasami jest bardzo przydatne, aby uzyskać auto increment primary key (id) wiersza, jeśli istnieje i 0 jeśli nie istnieje.

Oto jak można to zrobić w jednym zapytaniu:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-22 06:50:37

Uważam, że warto zwrócić uwagę, choć poruszono to w komentarzach, że w tej sytuacji:

SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1

Jest nadrzędna wobec:

SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1

Dzieje się tak dlatego, że pierwsze zapytanie może być spełnione przez indeks, podczas gdy drugie wymaga odszukania wiersza w górę (chyba że wszystkie kolumny tabeli znajdują się w indeksie).

Dodanie klauzuli LIMIT pozwala zatrzymać silnik po znalezieniu dowolnego wiersza.

Pierwsze zapytanie powinno być porównywalne do:

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

Który wysyła te same sygnały do silnika, ale i tak napisałbym 1 Aby usunąć wszelkie wątpliwości:

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

Może mieć sens dodanie EXISTS zawijania jest, jeśli wymagasz jawnego powrotu, gdy żadne wiersze nie pasują.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-19 14:56:24

Wybrałbym COUNT(1). Jest to szybsze niż COUNT(*), Ponieważ COUNT(*) sprawdza, czy przynajmniej jedna kolumna w tym wierszu jest != NULL. Nie potrzebujesz tego, zwłaszcza, że masz już warunek (klauzula WHERE). COUNT(1) zamiast tego testuje Ważność 1, która jest zawsze ważna i zajmuje dużo mniej czasu na testowanie.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-04 21:15:33

A hrabia zapytanie jest szybsze, choć może nie zauważalne, ale jeśli chodzi o uzyskanie pożądanego rezultatu, oba powinny być wystarczające.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-17 17:39:47

Dla tabel innych niż InnoDB można również użyć tabel schematów informacyjnych:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-04 21:12:33

LUB możesz wstawić surową część sql do warunków więc mam 'conditions' = > array('Member.id Nie w (Wybierz członkostwo.member_id FROM memberships AS 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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-29 09:18:01

COUNT(*) są zoptymalizowane w MySQL, więc pierwsze zapytanie prawdopodobnie będzie szybsze, ogólnie rzecz biorąc.

 -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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-04 21:01:53