How to Check if a Record Exists in a MySQL Database
Almost everyone has been in a circumstance when it is necessary to check whether a record exists in the MySQL database or not.
Let’s look through how to do that with the most suitable and easy command. Below you can find the right command and a common mistake that almost every beginner can make while trying to figure out the problem.
The Correct Command
If you want to check whether a record already exists in your database or not, you should run the following code:
// connect to database $mysqli = new mysqli("localhost","db_user","db_password","db_name"); $query = "SELECT * FROM products WHERE code = '$code'"; $result = $mysqli->query($query); if ($result) < if (mysqli_num_rows($result) > 0) < echo 'found!'; > else < echo 'not found'; > > else < echo 'Error: ' . mysqli_error(); > // close connection mysqli_close($mysqli); ?>
$query = "SELECT * FROM products WHERE code = '$code'"; $result = mysql_query($query); if ($result) < if (mysql_num_rows($result) > 0) < echo 'found!'; > else < echo 'not found'; > > else < echo 'Error: ' . mysql_error(); > ?>
A Common Mistake
Now, let’s check out a common mistake that we recommend you to overcome:
//Will NOT work $query = "SELECT * FROM products WHERE code = '$code'"; $result = mysql_query($query); if ($result) < echo 'found'; > else < echo 'not found'; > ?>
What is MySQL
MySQL is considered an open-source relational database management system. It is aimed at organizing data into one or more data tables.
Several popular applications such as Twitter, Facebook YouTube, Google apply MySQL for data storage purposes. It was initially made for limited usage. Yet, now it is compatible with many essential computing platforms such as macOS, Linux Ubuntu, and Microsoft Windows.
как работает WHERE EXISTS в MySQL
Нашёл у себя в коде запрос с WHERE EXISTS и решил разобраться, как оно работает.
Втыкал-то я его когда-то копи-пастом, толком не разобравшись.
А тут решил выяснить. Я в последнее время все запросы для себя стараюсь прояснять.
Стал читать доку, но как-то не въехал. А параллельно профилировал все варианты получения того же самого.
Сам запрос такой
SELECT SQL_NO_CACHE n.id, title, date_pub FROM news n WHERE NOT EXISTS
(SELECT * FROM categories c WHERE c.category = 5 AND c.id=n.id )
ORDER BY n.date_pub DESC limit 10
включил профилировние
set profiling=1;
выполнил запрос, и запросил результат профайлинга, который выдал мне таблицу, которая многое проясняет:
show profile;
+———————-+———-+
| Status | Duration |
+———————-+———-+
| starting | 0.000077 |
| checking permissions | 0.000004 |
| checking permissions | 0.000003 |
| Opening tables | 0.000023 |
| System lock | 0.000009 |
| init | 0.000030 |
| optimizing | 0.000009 |
| statistics | 0.000094 |
| preparing | 0.000058 |
| executing | 0.000003 |
| Sorting result | 0.000007 |
| Sending data | 0.000030 |
| optimizing | 0.000010 |
| statistics | 0.000112 |
| preparing | 0.000013 |
| executing | 0.000002 |
| Sending data | 0.000042 |
| executing | 0.000002 |
| Sending data | 0.000028 |
| executing | 0.000002 |
| Sending data | 0.000032 |
| executing | 0.000003 |
| Sending data | 0.000041 |
| executing | 0.000002 |
| Sending data | 0.000020 |
| executing | 0.000002 |
| Sending data | 0.000020 |
| executing | 0.000002 |
| Sending data | 0.000027 |
| executing | 0.000002 |
| Sending data | 0.000021 |
| executing | 0.000002 |
| Sending data | 0.000019 |
| executing | 0.000002 |
| Sending data | 0.000020 |
| executing | 0.000002 |
| Sending data | 0.000024 |
| end | 0.000004 |
| query end | 0.000003 |
| closing tables | 0.000006 |
| freeing items | 0.000020 |
| logging slow query | 0.000002 |
| cleaning up | 0.000003 |
+———————-+———-+
43 rows in set (0.00 sec)
Из хорошо видимых повторяющихся действий мы делаем предположение, что мускуль выполняет подзапрос для каждой найденной запросом строки, по результатам решая — добавлять или не добавлять её в итоговую выдачу.
причем подзапросы эти отрабатывают супербыстро, что видно из той же таблицы.
Предположение наше подкрепляется тем, что если в выдаче не встретилось категорий-исключений, то этих подзапросов выполняется 10 штук. Но если втречается такая категория, то количество подзапросов увеличивается: в приведённом примере их 11 — одна новость попала под фильтр, и вместо неё пришлось прочитать ещё одну.
То есть, это получается такой джойн для бедных, который, при этом, работает в 100 раз лучше запроса
WHERE id IN (SELECT id FROM table)
Но использовать его имеет смысл только с лимитированными запросами, поскольку если идёт большая выборка, то эти подзапросы, пусть даже и супербыстрые, в сумме всё равно дают ощутимое время выполнения.
Так что в итоге я всё равно отказался от WHERE EXISTS и сделал нормальный джойн,
SELECT * FROM news n LEFT JOIN categories c ON n.id = c.id and c.category = 5 WHERE c.id is null
который можно использовать как для получения самих новостей, так и их количества
(спасибо MiksIr с форума, который натыкал меня носом в идиотский тупняк с этим запросом)
Кстати, супербыстрота этих подзапросов объясняет эффективность handlerSocket-а: эти самые миллионные доли секунды из профайлинга — и есть реальное время обращения к storage engine, а остальное — это накладные расходы SQL-я.
как работает WHERE EXISTS в MySQL
Нашёл у себя в коде запрос с WHERE EXISTS и решил разобраться, как оно работает.
Втыкал-то я его когда-то копи-пастом, толком не разобравшись.
А тут решил выяснить. Я в последнее время все запросы для себя стараюсь прояснять.
Стал читать доку, но как-то не въехал. А параллельно профилировал все варианты получения того же самого.
Сам запрос такой
SELECT SQL_NO_CACHE n.id, title, date_pub FROM news n WHERE NOT EXISTS
(SELECT * FROM categories c WHERE c.category = 5 AND c.id=n.id )
ORDER BY n.date_pub DESC limit 10
включил профилировние
set profiling=1;
выполнил запрос, и запросил результат профайлинга, который выдал мне таблицу, которая многое проясняет:
show profile;
+———————-+———-+
| Status | Duration |
+———————-+———-+
| starting | 0.000077 |
| checking permissions | 0.000004 |
| checking permissions | 0.000003 |
| Opening tables | 0.000023 |
| System lock | 0.000009 |
| init | 0.000030 |
| optimizing | 0.000009 |
| statistics | 0.000094 |
| preparing | 0.000058 |
| executing | 0.000003 |
| Sorting result | 0.000007 |
| Sending data | 0.000030 |
| optimizing | 0.000010 |
| statistics | 0.000112 |
| preparing | 0.000013 |
| executing | 0.000002 |
| Sending data | 0.000042 |
| executing | 0.000002 |
| Sending data | 0.000028 |
| executing | 0.000002 |
| Sending data | 0.000032 |
| executing | 0.000003 |
| Sending data | 0.000041 |
| executing | 0.000002 |
| Sending data | 0.000020 |
| executing | 0.000002 |
| Sending data | 0.000020 |
| executing | 0.000002 |
| Sending data | 0.000027 |
| executing | 0.000002 |
| Sending data | 0.000021 |
| executing | 0.000002 |
| Sending data | 0.000019 |
| executing | 0.000002 |
| Sending data | 0.000020 |
| executing | 0.000002 |
| Sending data | 0.000024 |
| end | 0.000004 |
| query end | 0.000003 |
| closing tables | 0.000006 |
| freeing items | 0.000020 |
| logging slow query | 0.000002 |
| cleaning up | 0.000003 |
+———————-+———-+
43 rows in set (0.00 sec)
Из хорошо видимых повторяющихся действий мы делаем предположение, что мускуль выполняет подзапрос для каждой найденной запросом строки, по результатам решая — добавлять или не добавлять её в итоговую выдачу.
причем подзапросы эти отрабатывают супербыстро, что видно из той же таблицы.
Предположение наше подкрепляется тем, что если в выдаче не встретилось категорий-исключений, то этих подзапросов выполняется 10 штук. Но если втречается такая категория, то количество подзапросов увеличивается: в приведённом примере их 11 — одна новость попала под фильтр, и вместо неё пришлось прочитать ещё одну.
То есть, это получается такой джойн для бедных, который, при этом, работает в 100 раз лучше запроса
WHERE id IN (SELECT id FROM table)
Но использовать его имеет смысл только с лимитированными запросами, поскольку если идёт большая выборка, то эти подзапросы, пусть даже и супербыстрые, в сумме всё равно дают ощутимое время выполнения.
Так что в итоге я всё равно отказался от WHERE EXISTS и сделал нормальный джойн,
SELECT * FROM news n LEFT JOIN categories c ON n.id = c.id and c.category = 5 WHERE c.id is null
который можно использовать как для получения самих новостей, так и их количества
(спасибо MiksIr с форума, который натыкал меня носом в идиотский тупняк с этим запросом)
Кстати, супербыстрота этих подзапросов объясняет эффективность handlerSocket-а: эти самые миллионные доли секунды из профайлинга — и есть реальное время обращения к storage engine, а остальное — это накладные расходы SQL-я.