zoukankan      html  css  js  c++  java
  • select count() 效率比较

    MyISAM引擎把一个表的总行数存储在磁盘,如果执行select count(*)直接返回。

    InnoDB执行select count(*)的时候需要把数据一行一行的从引擎读出来,然后累加计数。
    count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。最后返回累计值。

    count(*) 跟 count(1) 的结果一样,都包括对NULL的统计,而count(id) 是不包括NULL的统计。 当用某一具体字段作为count函数的参数时,值为null的记录是不被计算的。
    但是 count(*) 是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count(*) 肯定不是 null,按行累加。
    对于 count(1) 来说,InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。
    对于 count(主键 id) 来说,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。
    单看这两个用法的差别的话,你能对比出来,count(1) 执行得要比 count(主键 id) 快。因为从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。
    count(普通索引) 二级索引


    count(*)=count(1)>count(主键)>count(普通索引)>count(无索引)

    我们把COUNT的使用情况分为以下3类:

    ① COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)
    ② COUNT(允许为空列)
    ③ COUNT(DISTINCT 列名)

    下面分别从查询结果和效率方面做个比较:
    (一)结果区别
    ① COUNT(1)、COUNT(*)、COUNT(ROWID)、COUNT(常量)、COUNT(主键)、COUNT(非空列)这几种方式统计的行数是表中所有存在的行的总数,包括值为NULL的行和非空行。所以,这几种方式的执行结果相同。这里的常量可以为数字或字符串,例如,COUNT(2)、COUNT(333)、COUNT('x')、COUNT('xiaomaimiao')。需要注意的是:这里的COUNT(1)中的“1”并不表示表中的第一列,它其实是一个表达式,可以换成任意数字或字符或表达式。
    ② COUNT(允许为空列) 这种方式统计的行数不会包括字段值为NULL的行。
    ③ COUNT(DISTINCT 列名) 得到的结果是除去值为NULL和重复数据后的结果。
    ④ “SELECT COUNT(''),COUNT(NULL) FROM T_COUNT_LHR;”返回0行。

    (二)效率、索引
    ① 如果存在主键或非空列上的索引,那么COUNT(1)、COUNT(*)、COUNT(ROWID)、COUNT(常量)、COUNT(主键)、COUNT(非空列)会首先选择主键上的索引快速全扫描(INDEX FAST FULL SCAN)。若主键不存在则会选择非空列上的索引。若非空列上没有索引则肯定走全表扫描(TABLE ACCESS FULL)。其中,COUNT(ROWID)在走索引的时候比其它几种方式要慢。通过10053事件可以看到这几种方式除了COUNT(ROWID)之外,其它最终都会转换成COUNT(*)的方式来执行。
    ② 对于COUNT(COL1)来说,只要列字段上有索引则会选择索引快速全扫描(INDEX FAST FULL SCAN)。而对于“SELECT COL1”来说,除非列上有NOT NULL约束,否则执行计划会选择全表扫描。
    ③ COUNT(DISTINCT 列名) 若列上有索引,且有非空约束或在WHERE子句中使用IS NOT NULL,则会选择索引快速全扫描。其余情况选择全表扫描。

  • 相关阅读:
    .NET组件控件实例编程系列——4.多列下拉框和鼠标相关组件
    仿查询分析器的C#计算器——2.记号对象
    .NET组件控件实例编程系列——1.开篇
    仿查询分析器的C#计算器——1.初步分析
    WCF续写. IIS托管
    NhibernateReview
    文件路径,文件名,扩展名 常用操作
    Resharper.alt+enter
    textFieldShouldReturn 键盘无法消失 无法return的问题
    NHibernate原生SQL查询
  • 原文地址:https://www.cnblogs.com/shijianchuzhenzhi/p/13070264.html
Copyright © 2011-2022 走看看