美文网首页
SELECT COUNT

SELECT COUNT

作者: 帮我的鸵鸟盖个章 | 来源:发表于2019-10-29 17:45 被阅读0次

    参考:

    不就是SELECT COUNT语句吗,竟然能被面试官虐的体无完肤

    MySQL 5.7下InnoDB对COUNT(*)的优化

    SELECT COUNT

    count的定义:

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

    阿里巴巴规范

    1、不要使用 count(列名)或 count(常量)来替代 count(*),count(*)是 SQL92 定义的 标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。 
    说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
    

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

    1. COUNT有几种用法?
      count(*),count(列名)count(常量)

    2. COUNT(字段名)COUNT(*)的查询结果有什么不同?

      count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

    3. COUNT(1)COUNT(*)之间有什么不同?

      MySQL官方文档说明:

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

      说得很清楚,没有什么不同。

    4. MySQLMyISAM引擎对COUNT(*)做了哪些优化?

      加缓存记录。

      MyISAM不支持事务,MyISAM中的锁是表级锁
      MyISAM做了一个简单的优化,那就是它可以把表的总行数单独记录下来,如果从一张表中使用COUNT(*)进行查询的时候,可以直接返回这个记录下来的数值就可以了,当然,前提是不能有where条件。

    5. MySQLInnoDB引擎对COUNT(*)做了哪些优化?

      InnoDB支持事务,并且支持行级锁。InnoDB中,使用COUNT(*)查询行数的时候,不可避免的要进行扫表了,那么,就可以在扫表过程中下功夫来优化效率了。

      MySQL 8.0.13开始,针对InnoDBSELECT COUNT(*) FROM tbl_name语句,确实在扫表的过程中做了一些优化。前提是查询语句中不包含WHEREGROUP BY等条件。

      我们知道,COUNT(*)的目的只是为了统计总行数,所以,他根本不关心自己查到的具体值,所以,他如果能够在扫表的过程中,选择一个成本较低的索引进行的话,那就可以大大节省时间。

      我们知道,InnoDB中索引分为聚簇索引(主键索引)和非聚簇索引(非主键索引),聚簇索引的叶子节点中保存的是整行记录,而非聚簇索引的叶子节点中保存的是该行记录的主键的值。

      所以,相比之下,非聚簇索引要比聚簇索引小很多,所以MySQL会优先选择最小的非聚簇索引来扫表。所以,当我们建表的时候,除了主键索引以外,创建一个非主键索引还是有必要的。
      这些优化的前提都是查询语句中不包含WHERE以及GROUP BY条件。

    **COUNT(字段)**
    
    最后,就是我们一直还没提到的`COUNT(字段)`,他的查询就比较简单粗暴了,就是进行全表扫描,然后判断指定字段的值是不是为`NULL`,不为`NULL`则累加。
    
    相比`COUNT(*)`,`COUNT(字段)`多了一个步骤就是判断所查询的字段是否为NULL,所以他的性能要比`COUNT(*)`慢。
    

    相关文章

      网友评论

          本文标题:SELECT COUNT

          本文链接:https://www.haomeiwen.com/subject/fgmgvctx.html