MySQL之COUNT(*)效率

记得又一次例会大家讨论到了count(*)和count(col)的问题,大家当时说的都count(col)比较快,最近看了几篇文章,发现大家的这种观点可能是有问题的。关于这个问题网上有很多版本,看的我都凌乱了。我还是整理了一下。

在不加WHERE限制条件的情况下,COUNT(*)与COUNT(COL)基本可以认为是等价的;但是在有WHERE限制条件的情况下,COUNT(*)会比COUNT(COL)快非常多;

具体的数据参考如下:

 

mysql> SELECT COUNT(*) FROM testCount where fid = 604;
+————+
| COUNT(fid) |
+————+
| 79000 |
+————+
1 row in set (0.03 sec)

mysql> SELECT COUNT(tid) FROM testCount where fid = 604;
+————+
| COUNT(tid) |
+————+
| 79000 |
+————+
1 row in set (0.33 sec)

mysql> SELECT COUNT(pid) FROM testCount where fid = 604;
+————+
| COUNT(pid) |
+————+
| 79000 |
+————+
1 row in set (0.33 sec)

仔细查阅累下手册,发现当没有WHERE语句对于整个mysql的表进行count运算的时候,MyISAM类型的表中保存有总的行数,而当添加有WHERE限定语句的时候Mysql需要对整个表进行检索从而得出count的数值

COUNT(*)通常是对主键进行索引扫描,而COUNT(COL)就不一定了,另外前者是统计表中的所有符合的纪录总数,而后者是计算表中所有符合的COL的纪录数。还有有区别的。

COUNT时的WHERE

   简单说下,就是COUNT的时候,如果没有WHERE限制的话,MySQL直接返回保存有总的行数
   而在有WHERE限制的情况下,总是需要对MySQL进行全表遍历。

优化总结:(网上的观点)

   1.任何情况下SELECT COUNT(*) FROM tablename是最优选择;
   2.尽量减少SELECT COUNT(*) FROM tablename WHERE COL = ‘value’ 这种查询;
   3.杜绝SELECT COUNT(COL) FROM tablename WHERE COL2 = ‘value’ 的出现。

 

Count(1)和count(*)比较

比较这两个的方法很简单,使用set showplan_text on命令可以查看语句的执行计划

 

select count(*) from test

|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1005],0)))

|--Stream Aggregate(DEFINE:([Expr1005]=Count(*)))

|--Table Scan(OBJECT:([AdventureWorks].[dbo].[test]))

 

select count(1) from test

|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1005],0)))

|--Stream Aggregate(DEFINE:([Expr1005]=Count(*)))

|--Table Scan(OBJECT:([AdventureWorks].[dbo].[test]))

对比下两个执行计划我们可以发现是完全一样的,这也就说明count(*)和count(1)的执行效率是完全一样的,根本不存在所谓的单列扫描和多列扫描的问题。

count(col)与count(*)的对比

同样,我们先看一下两个不同count方式的执行计划。

count(*)的执行计划看上面的例子。

count(b)的执行计划:

select count(b) from test

 

|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1005],0)))

|--Stream Aggregate(DEFINE:([Expr1005]=COUNT([AdventureWorks].[dbo].[test].[b])))

|--Table Scan(OBJECT:([AdventureWorks].[dbo].[test]))

 

现在能看到这两个执行计划唯一不同的地方就是COUNT的内容,对于count(*)是"|—Stream Aggregate(DEFINE:([Expr1005]=count(*)))",对于count(b)是"|—Stream Aggregate(DEFINE:([Expr1005]=COUNT([AdventureWorks].[dbo].[test].[b])))",那这两种count方式会不会有什么不一样呢?

让我们先看一下BOL里面对count(*)以及count(col)的说明:

COUNT(*) 返回组中的项数。包括 NULL 值和重复项。

COUNT(ALL expression) 对组中的每一行都计算 expression 并返回非空值的数量。

expression

除 text、image 或 ntext 以外任何类型的表达式。不允许使用聚合函数和子查询。

*

指定应该计算所有行以返回表中行的总数。COUNT(*) 不需要任何参数,而且不能与 DISTINCT 一起使用。

COUNT(*) 不需要 expression 参数,因为根据定义,该函数不使用有关任何特定列的信息。

COUNT(*) 返回指定表中行数而不删除副本。它对各行分别计数。包括包含空值的行。

也就是说count(*)只是返回表中行数,因此SQL Server在处理count(*)的时候只需要找到属于表的数据块块头,然后计算一下行数就行了,而不用去读取里面数据列的数据。而对于count(col)就不一样了,为了去除col列中包含的NULL行,SQL Server必须读取该col的每一行的值,然后确认下是否为NULL,然后在进行计数。因此count(*)应该是比count(col)快的,下面我们来验证一下。

我们通过在同样的条件下将select count(…) from test执行1000次来看两种count方式是否是一样的:

先看count(*)

declare @n int, @a int

set @n = 1

while @n <= 1000

begin

select @a = count(*) from test

set @n = @n+1

end

?

/*------------------------------

?执行结果:29s

?-----------------------------*/

接着看count(col)

declare @n int, @a int

set @n = 1

while @n <= 1000

begin

select @a = count(b) from test

set @n = @n+1

end

?

/*------------------------------

?执行结果:57s

?-----------------------------*/

从执行结果可以看出相差还是很大的,count(*)比count(col)快了一倍。

不过因为count(*)和count(col)使用的目的是不一样的,在必须要使用count(col)的时候还是要用的,只是在统计表全部行数的时候count(*)就是最佳的选择了。

 

最后奉上我的建议:

    在大家写完语句后如果想优化,可以通过set showplan_text on 来查看语句的执行计划,进行优化。明确了优化目标之后,我们需要确定达到我们目标的方法。对于 SQL 语句来说,加快语句的执行速度的方法,那就是改变 SQL 的执行计划,让他尽量“少走弯路”,尽量通过各种“捷径”来找到我们需要的数据,以达到 “减少 IO 次数” 和 “降低 CPU 计算” 的目标。

   另外一点就是count(col),和count(*)返回的结果其实不一样。

    count(column) 是表示结果集中有多少个column字段不为空的记录;

  count(*) 是表示整个结果集有多少条记录;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值