Best way to test if a row exists in a MySQL table
I'm trying to find out if a row exists in a table. Using MySQL, is it better to do a query like this:
SELECT COUNT(*) AS total FROM table1 WHERE ...
and check to see if the total is non-zero or is it better to do a query like this:
SELECT * FROM table1 WHERE ... LIMIT 1
and check to see if any rows were returned?
In both queries, the WHERE clause uses an index.
You could also try EXISTS
:
SELECT EXISTS(SELECT * FROM table1 WHERE ...)
and per the documentation, you can SELECT
anything.
Traditionally, an EXISTS subquery starts with SELECT *, but it could begin with SELECT 5 or SELECT column1 or anything at all. MySQL ignores the SELECT list in such a subquery, so it makes no difference.
I have made some researches on this subject recently. The way to implement it has to be different if the field is a TEXT field, a non unique field.
I have made some tests with a TEXT field. Considering the fact that we have a table with 1M entries. 37 entries are equal to 'something':
-
SELECT * FROM test WHERE text LIKE '%something%' LIMIT 1
withmysql_num_rows()
: 0.039061069488525s. (FASTER) -
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.
But now, with a BIGINT PK field, only one entry is equal to '321321' :
-
SELECT * FROM test2 WHERE id ='321321' LIMIT 1
withmysql_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. (FASTER)
A short example of @ChrisThompson's answer
Example:
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)
Using an alias:
mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
In my research, I can find the result getting on following speed.
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)