Ber*_*hen 313 mysql sql performance exists
我试图找出表中是否存在行.使用MySQL,最好像这样进行查询:
SELECT COUNT(*) AS total FROM table1 WHERE ...
Run Code Online (Sandbox Code Playgroud)
并检查总数是否为非零或是否更好地执行这样的查询:
SELECT * FROM table1 WHERE ... LIMIT 1
Run Code Online (Sandbox Code Playgroud)
并检查是否有任何行返回?
在两个查询中,WHERE子句都使用索引.
Chr*_*son 443
你也可以尝试使用
SELECT EXISTS(SELECT * FROM table1 WHERE ...)
Run Code Online (Sandbox Code Playgroud)
根据文件
根据以下评论:
SELECT EXISTS(SELECT * FROM table1 WHERE ...)
Run Code Online (Sandbox Code Playgroud)
Lau*_* W. 172
我最近对这个问题进行了一些研究.如果字段是TEXT字段,非唯一字段,则实现它的方式必须不同.
我用TEXT字段做了一些测试.考虑到我们有一个包含1M条目的表的事实.37个条目等于'某事':
SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1
与
mysql_num_rows()
:0.039061069488525s.(快点)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
搭配
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 EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1)
:0.00020313262939453s.(快点)jal*_*tek 23
@ 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)
Run Code Online (Sandbox Code Playgroud)
使用别名:
mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
小智 11
在我的研究中,我可以发现结果跟随速度.
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)
Run Code Online (Sandbox Code Playgroud)
我认为值得指出的是,尽管在评论中已经提到了这种情况:
SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1
Run Code Online (Sandbox Code Playgroud)
优于:
SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1
Run Code Online (Sandbox Code Playgroud)
这是因为第一个查询可以由索引满足,而第二个查询则需要查找行(除非所有表的列都在使用的索引中)。
添加该LIMIT
子句可使引擎在找到任何行后停止。
第一个查询应类似于:
SELECT EXISTS(SELECT * FROM my_table WHERE *indexed_condition*)
Run Code Online (Sandbox Code Playgroud)
它向引擎发送相同的信号(1 / *在这里没有区别),但是我仍然会写1来加强使用时的习惯EXISTS
:
SELECT EXISTS(SELECT 1 FROM my_table WHERE *indexed_condition*)
Run Code Online (Sandbox Code Playgroud)
EXISTS
如果在没有行匹配的情况下需要显式返回,则添加包装可能是有意义的。