SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1
优于:
SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1
这是因为索引可以满足第一个查询,而第二个查询需要查找行(除非可能所有表的列都在使用的索引中) .
添加 LIMIT 子句允许引擎在找到任何行后停止 .
第一个查询应该与:
SELECT EXISTS(SELECT * FROM my_table WHERE *indexed_condition*)
它向发动机发送相同的信号,但我仍然写1以消除任何疑问:
SELECT EXISTS(SELECT 1 FROM my_table WHERE *indexed_condition*)
如果在没有行匹配时需要显式返回,则添加 EXISTS 包装可能是有意义的 .
6
在我的研究中,我可以发现结果跟随速度 .
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)
2
COUNT 查询速度更快,但可能并不明显,但只要获得所需结果,两者都应该足够了 .
-1
@ ChrisThompson答案的简短例子
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)
使用别名:
mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
12 回答
COUNT(*)
在MySQL中进行了优化,因此一般来说,前一个查询可能更快 .我最近对这个问题做了一些研究 . 如果字段是TEXT字段,非唯一字段,则实现它的方式必须不同 .
我用TEXT字段做了一些测试 . 考虑到我们有一个包含1M条目的表的事实 . 37个条目等于'某事':
SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1
与mysql_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 .但现在,使用BIGINT PK字段,只有一个条目等于'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)我跟
COUNT(1)
一起去 . 它比COUNT(*)
更快,因为COUNT(*)
测试以查看该行中是否至少有一列是!= NULL . 您不需要这样,特别是因为您已经有条件(WHERE
子句) .COUNT(1)
而不是测试1
的有效性,它始终有效并且测试时间要少得多 .或者您可以将原始sql部分插入条件,所以我有'conditions' =>数组('Member.id NOT IN (SELECT Membership.member_id FROM memberships AS Membership)')
你也可以尝试使用
每the documentation
Per a comment below:
我觉得值得指出的是,尽管评论中提到了这一点,但在这种情况下:
优于:
这是因为索引可以满足第一个查询,而第二个查询需要查找行(除非可能所有表的列都在使用的索引中) .
添加
LIMIT
子句允许引擎在找到任何行后停止 .第一个查询应该与:
它向发动机发送相同的信号,但我仍然写1以消除任何疑问:
如果在没有行匹配时需要显式返回,则添加
EXISTS
包装可能是有意义的 .在我的研究中,我可以发现结果跟随速度 .
COUNT 查询速度更快,但可能并不明显,但只要获得所需结果,两者都应该足够了 .
@ ChrisThompson答案的简短例子
Example:
使用别名:
建议你不要使用
Count
因为count总是为db使用SELECT 1
做额外的加载,如果你的记录在那里它会返回 1 否则它返回null并且你可以处理它 .有时,如果存在行的自动增量主键(
id
),则非常方便,如果不存在,则为0
.以下是在单个查询中如何完成此操作:
对于非InnoDB表,您还可以使用信息模式表:
http://dev.mysql.com/doc/refman/5.1/en/tables-table.html