zoukankan      html  css  js  c++  java
  • MySQL COUNT(*) & COUNT(1) & COUNT(col) 比较分析

    在面试的时候我们会经常遇到这个问题:

    MySQL 中,COUNT(*)、COUNT(1)、COUNT(col) 有区别吗?

    有区别。

    接下来我们分析一下这三者有什么样的区别。

    一、SQL Syntax & Semantics

    从语义角度看,它们有不同的含义。

    COUNT(expr)返回查询到的行中 expr is not-NULL 的个数,返回类型为 BIGINT(8 bytes)。

    Returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement. The result is a BIGINT value.

    COUNT(*) 有点不同,它返回查询到的结果集中的行的个数,不论这些行是否含有 NULL 值。

    COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values.

    COUNT(1) 返回查询到的行中第一列 not NULL 的个数。

    COUNT(col) 返回查询到的行中 col 列中 not NULL 的个数。

    二、查询性能

    在 MySQL 中讨论查询性能时,我们需要区分存储引擎。

    不同的存储引擎以不同的方式存储数据,这决定了最终的操作效率。

    MyISAM 的主键、辅助索引都是非聚簇索引,B+树的叶节点包含的是数据的地址。

    InnoDB 的主键是聚簇索引,叶节点存放的是数据本身;辅助索引是非聚簇索引,叶节点存放的是主键。

    1、MyISAM

    MyISAM 为每张表存储了一个准确(exact)的 row count。

    因此,MyISAM 可以为 COUNT(*) 提供查询优化:当某个 SELECT 语句仅仅查询一张表、不查询其他列、没有查询条件(WHERE 子句)时,COUNT(*) 可以很快地返回这个 row count(e.g. SELECT COUNT(*) FROM tbl_name)。

    当第一列定义为 NOT NULL 时,COUNT(1) 和 COUNT(*) 具有相同的查询性能。

    2、InnoDB

    InnoDB 是一款 transactional 存储引擎。

    可能有多个事务并发操作一张表,所以 InnoDB 无法为每张表存储一个准确的 row count(因为不同的 transaction 可能会看到不同的 row count,row count 很难准确)。

    对于 InnoDB 而言,COUNT(*)、 COUNT(1) 没有性能上的差异。

    COUNT(*) 会利用索引:在 MySQL 5.7.18 之前,会利用聚簇索引;在 MySQL 5.7.18 之后,会利用一个最小的辅助索引(有的话)。

    三、参考资料:

    What is better in MYSQL count(*) or count(1)?

    COUNT(expr)

    Restrictions on InnoDB Tables

     

     

     

     

  • 相关阅读:
    JavaScript提供了哪些定时器
    谈谈对CSS盒子模型的理解
    我们来谈谈类的加载机制
    谈谈你对ThreadLocal的理解
    谈谈你对线程安全的理解?
    JDK提供的线程池有哪些?实际开发我们该怎么使用?
    Pytest系列(7)
    Pytest系列(6)
    Pytest系列(5)
    Pytest系列(4)
  • 原文地址:https://www.cnblogs.com/huangzejun/p/8854279.html
Copyright © 2011-2022 走看看