对比MySQL中的count(*)、count(1)、count(主键列)与count(普通列)的性能差异

27 阅读2分钟

在MySQL中,COUNT() 函数是用来统计行数的重要聚合函数。针对 COUNT(*)COUNT(1)COUNT(主键列)和 COUNT(普通列),它们的用途和性能各有差异。

首先,COUNT(*) 是用来统计表中所有行的数量,不管列中的值是否为NULL。COUNT(*)会扫描整个表,或者如果有的话使用最小的全表覆盖索引来统计行数。

COUNT(1) 实际上和 COUNT(*)非常接近,在很多数据库系统中,包括MySQL,在执行层面它们是等效的。当调用 COUNT(1)时,数据库不会去检查任何特定列的值,它只是表示每行都要计数,和 COUNT(*)一样。

COUNT(主键列) 中的主键列通常是被索引的。在MySQL中,主键索引是一个唯一索引,其数据结构是B-Tree(或者在InnoDB存储引擎中是B+Tree)。当你使用 COUNT(主键列)时,MySQL可以快速地使用该索引来统计行数,因为主键列不会有NULL值,因此这种计数方式通常很高效。

COUNT(普通列) 则是统计特定普通列非NULL值的行数。当对普通列使用 COUNT()时,必须检查每行该列的值是否为NULL,之后才能决定是否计数,如果该列上没有索引,则可能需要扫描全表来得到结果,这可能会比 COUNT(*)和 COUNT(1)慢。如果该普通列有索引,那么性能可能会比未索引的情况好,但是仍然可能比 COUNT(主键列)慢,因为即使是索引,普通索引也不一定是覆盖整个表的。

在实际的查询性能中,使用 COUNT(主键列)通常是最快的,因为数据库可以利用主键索引来快速地统计行数。COUNT(*)和 COUNT(1)是类似的,它们通常比 COUNT(普通列)快,因为它们不需要检查特定列的值。然而,如果一个普通列被频繁地用来做 COUNT()操作,且该列上有非NULL保证,则建立索引可以提高性能。

综上,当需要统计行数而不关心列值时,COUNT(*)和 COUNT(1)通常是更好的选择,因为它们提供了较好的性能且用法简单;当你确定一个列不含有NULL值,特别是对于主键列,使用 COUNT(主键列)可以进一步提高效率