为什么Select 1比Select count(*)更快?

12

在Oracle中,当查询行是否存在时,为什么选择Select 1比Select count(*)更快?


1
不知道你使用的是哪个关系型数据库引擎,就无法正确回答。不同的引擎行为也不同。 - Glen
2
你的意思是“为什么select count(1)比Select count(*)更快吗?” - Tony Andrews
我的意思是“选择1”。我正在查看一些旧的、离线的编码标准文档,其中声称“选择1”比“选择count(*)”更快,并且是查询行存在的首选方式。该文档没有提供为什么这是一种“性能增强”技术的技术解释。当我在网上搜索时,我发现了像AskTom线程和辩论之类的东西...但我没有看到一个清晰、明确的答案。 - user290
我更新了我的回答。简短的回答是COUNT(*)和COUNT(1)之间没有区别。 - Justin Cave
5
你能回答哪个问题更快?(a) 电话簿中是否有人名叫“史密斯”?(b) 电话簿中叫做史密斯的人有多少个? - WW.
8个回答

16

如果RDBMS支持,最好使用EXISTS或等效的方法,这样可以尽早停止处理匹配的行。


5
我们应该只使用COUNT()函数来获取实际涉及记录的数量。 - APC

14

由于Oracle在PL/SQL中不支持IF EXISTS,因此CodeByMidnight的建议通常会使用EXISTS来完成类似的操作,例如:

SELECT 1 
  INTO l_local_variable 
  FROM dual 
 WHERE EXISTS( 
    SELECT 1 
      FROM some_table 
     WHERE some_column = some_condition ); 

Oracle知道只要找到一个匹配条件的行就可以停止处理WHERE EXISTS子句,因此不必计算可能匹配条件的大量行数。当您检查涉及未索引列或可能返回大量行的条件时,这个问题显然就不那么重要了,当然,如果您正在检查特定键值是否存在行,则这样做并不会带来太多问题。

更新:根据原始发布者在评论中提供的澄清,简短而明确的答案是“SELECT 1”或“SELECT COUNT(1)”不比“SELECT COUNT(*)”更快。与您查看的任何编码指南相反,“COUNT(*)”是计算所有行的首选方法。曾经有一个关于“COUNT(1)”更快的老传说。至少在过去十年发布的任何Oracle版本中都不是如此,并且很可能从来没有。然而,这是一个广为人知的信仰。今天,对于使用“COUNT(1)”而不是“COUNT(*)”的代码,我通常怀疑作者容易相信各种Oracle的神话,因此建议使用“COUNT(*)”。


2

如果select count(*)没有得到有效优化,那我会感到惊讶。因为不需要加载所有的列,也不会有与列相关的处理。


1
Oracle将count(*)视为与count(1),count(null),count('任何原子值')完全相同。 - Jeffrey Kemp


0

由于星号将所有列计入统计,因此“1”是一种本地数据类型。

在MySQL中,“SELECT COUNT(主键名称)”应该与您的SELECT 1一样快。 它是索引的计数。对索引进行计数应该非常快;)


0

0

其他条件相同的情况下,"select 1 from my_table""select count(*) from my_table" 更快地返回第一个结果,但如果您检索查询的所有结果,则 count(*) 的速度会更快,因为它涉及的数据要少得多(1个整数,而不是表中每行的1个整数)。


0

如果您正在使用postgresql,则count(1)实际上比count(*)慢。

根据:https://www.citusdata.com/blog/2016/10/12/count-performance/

关于count(1)count(*)的说明。人们可能认为count(1)会更快,因为count(*)似乎要查询整个行的数据。然而事实恰恰相反。星号在这里是无意义的,不像在SELECT *中的用法。PostgreSQL将表达式count(*)解析为一个特殊情况,不带参数。(历史上,该表达式应该被定义为count()。)另一方面,count(1)需要一个参数,PostgreSQL必须在每一行上检查其参数1是否确实不为空。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接