我试图找出一行是否存在于一个表中。使用MySQL,是更好的做这样的查询:

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

然后检查总数是否为非零,或者像这样查询是否更好:

SELECT * FROM table1 WHERE ... LIMIT 1

并检查是否返回了任何行?

在这两个查询中,WHERE子句都使用索引。


当前回答

我最近在这个问题上做了一些研究。如果字段是一个非唯一的TEXT字段,实现它的方式必须不同。

我已经做了一些测试与文本字段。考虑到我们有一个有1M个条目的表。37个条目等于“某物”:

从测试中选择“%something%”这样的文本 Mysql_num_rows (): 0.039061069488525s。(快) SELECT count(*) FROM test WHERE text LIKE '%something%: 16.028197050095 s。 SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%'): 0.87045907974243 s。 SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1): 0.044898986816406s。

但是现在,在BIGINT PK字段中,只有一个条目等于'321321':

SELECT * FROM test2 WHERE id ='321321 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 (SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1): 0.0002031326293943s。(快)

其他回答

对于非innodb表,你也可以使用信息模式表:

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

下面是@ChrisThompson回答的一个小例子

例子:

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)

使用别名:

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

COUNT查询更快,虽然可能不是很明显,但就获得所需的结果而言,两者都应该足够了。

有时,如果行存在,则获取该行的自动递增主键(id),如果不存在则获取0,这非常方便。

以下是如何在单个查询中完成的:

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

我最近在这个问题上做了一些研究。如果字段是一个非唯一的TEXT字段,实现它的方式必须不同。

我已经做了一些测试与文本字段。考虑到我们有一个有1M个条目的表。37个条目等于“某物”:

从测试中选择“%something%”这样的文本 Mysql_num_rows (): 0.039061069488525s。(快) SELECT count(*) FROM test WHERE text LIKE '%something%: 16.028197050095 s。 SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%'): 0.87045907974243 s。 SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1): 0.044898986816406s。

但是现在,在BIGINT PK字段中,只有一个条目等于'321321':

SELECT * FROM test2 WHERE id ='321321 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 (SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1): 0.0002031326293943s。(快)