• count(1)比count(*)效率高?


    SELECT COUNT(*) FROM table_name是个再常见不过的统计需求了。
    本文带你了解下MysqlCOUNT函数。

    一、COUNT函数

    关于COUNT函数,在MySQL官网中有详细介绍

    风尘博客

    翻译一下:

    1. COUNT(expr) ,返回SELECT语句检索的行中expr的值不为NULL的数量,结果是一个BIGINT值。
    2. 如果查询结果没有命中任何记录,则返回0
    3. COUNT(*) 的统计结果中,会包含值为NULL的行数。

    《阿里巴巴Java开发手册》也有如下要求:

    风尘博客

    二、COUNT(列名)COUNT(常量)COUNT(*)

    前面我们提到过COUNT(expr)用于做行数统计,那么COUNT(列名)COUNT(常量)COUNT(*)这三种语法中,expr分别是列名、 常量 和 *

    2.1 COUNT(*)COUNT(常量)

    在列名、常量和 *这三个条件中,常量是一个固定值,肯定不为NULL*可以理解为查询整行,所以肯定也不为NULL,那么就只有列名的查询结果可能是NULL

    所以, COUNT(常量)COUNT(*)表示的是直接查询符合条件的数据库表的行数。而COUNT(列名)表示的是查询符合条件的列的值不为NULL的行数。

    2.2 COUNT(*)COUNT(1)区别

    COUNT(1)就是COUNT(常量),对于这二者到底有没有区别:

    1. 有的说COUNT(*)执行时会转换成COUNT(1),所以COUNT(1)少了转换步骤,所以更快。
    2. 还有的说,因为MySQL针对COUNT(*)做了特殊优化,所以COUNT(*)更快。

    到底哪种说法是对的?看下MySQL官方文档:

    InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.
    

    通过文档,对于COUNT(1)COUNT(*)MySQL的优化是完全一样的,根本不存在谁比谁快!

    2.3 COUNT(列名)

    相较于前两者,COUNT(列名)的查询就比较简单粗暴了,就是进行全表扫描,然后判断指定字段的值是不是为NULL,不为NULL则累加。

    相比COUNT(*)COUNT(列名)多了一个步骤就是判断所查询的字段是否为NULL,所以他的性能要比COUNT(*)慢。
    here和group的条件查询。

    2.4 SQL92

    除了查询得到结果集有区别之外,COUNT(*)相比COUNT(常量)COUNT(列名)来讲,COUNT(*)SQL92定义的标准统计行数的语法,因为他是标准语法,所以MySQL数据库对他进行过很多优化。

    SQL92,是数据库的一个ANSI/ISO标准。它定义了一种语言(SQL)以及数据库的行为(事务、隔离级别等)。

    2.5 COUNT(*)优化

    因为COUNT(*)SQL92定义的标准统计行数的语法,所以MySQL对其进行了很多优化:

    1. MyISAM中会直接把表的总行数单独记录下来供COUNT(*)查询
    2. InnoDB会在扫表的时候选择最小的索引来降低成本。

    这些优化的前提都是没有进行wheregroup的条件查询,更多请参考MySQL 全表 COUNT(*) 简述

    三、总结

    COUNT函数用于统计表行数,按照效率比较的话:

    count(*)=count(常量)>count(列名)
    

    3.1 小建议

    既然 count(*) 在查询上依赖于所有的数据集,所以我们在设计上也需要尽量的规避全量 count

    通常情况我们针对可预见count 查询会做适当的缓存,可以是 Redis,也可以是独立的 MySQL count 表。

    3.2 技术交流

    1. 风尘博客
    2. 风尘博客-掘金
    3. 风尘博客-博客园
    4. Github
  • 相关阅读:
    BAPI_TRANSACTION_COMMIT的使用方法(转)
    Win7 64bit系统下未能加载文件或程序集“System.Data.SQLite”的解决办法
    在Windows XP环境中配置OPC服务器时的设置方式
    关于异常“The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine”的处理
    MSChart使用做折线图饼图(转)
    C#如何导入内文至SAP(转)
    经典Sql大全转
    工程师突击:SAP ABAP实用程序开发攻略(转)
    如何使用ExtJS Design中生成的代码
    ExtJS 4 学习(1)环境配置及注意点
  • 原文地址:https://www.cnblogs.com/vandusty/p/12248605.html
Copyright © 2020-2023  润新知