当前位置:  开发笔记 > 后端 > 正文

我应该COUNT(*)吗?

如何解决《我应该COUNT(*)吗?》经验,为你挑选了5个好方法。

我知道做这样的查询通常是一个坏主意:

SELECT * FROM `group_relations`

但是,当我只想要计数时,我是否应该进行此查询,因为这样可以更改表但仍会产生相同的结果.

SELECT COUNT(*) FROM `group_relations`

或者更具特色

SELECT COUNT(`group_id`) FROM `group_relations`

我觉得后者可能会更快,但还有其他事情需要考虑吗?

更新:我在这种情况下使用InnoDB,抱歉没有更具体.



1> pilif..:

如果相关列是NOT NULL,则两个查询都是等效的.当group_id包含空值时

select count(*)

将计算所有行,而

select count(group_id)

将仅计算group_id不为null的行.

此外,某些数据库系统(如MySQL)会在您请求count(*)时使用优化,这使得此类查询比特定查询快一点.

就个人而言,在计算时,我正在使用空值来计算(*)以确保安全.


是的,但是a)当我编写响应时,InnoDB注释不存在,而b)当InnoDB无法优化计数时,count(*)不会比count(group_id)更快或更慢.即使在MyISAM上,当你添加一个WHERE子句时,你也会失去速度优势

2> Sebastian Di..:

如果我没记错,在MYSQL COUNT(*)中计算所有行,而COUNT(column_name)只计算给定列中具有非NULL值的行.



3> Eran Galperi..:

COUNT(*)计算所有行,而COUNT(column_name)将仅计算指定列中没有NULL值的行.

在MySQL中需要注意的重要事项

对于*或非空列,COUNT()在MyISAM表上非常快,因为行计数被缓存.InnoDB没有行计数缓存,因此COUNT(*)或COUNT(column_name)的性能没有差异,无论该列是否为null.您可以在MySQL性能博客上阅读有关此帖子差异的更多信息.



4> Sergio..:

如果您尝试SELECT COUNT(1) FROMgroup_relations它会更快一些,因为它不会尝试从列中检索信息.

编辑:我刚做了一些研究,发现这只发生在一些数据库中.在sqlserver中使用1或*是一样的,但在oracle上使用1会更快.

http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/9367c580-087a-4fc1-bf88-91a51a4ee018/

显然,它们在mysql中没有区别,就像sqlserver一样,解析器似乎将查询更改为select(1).对不起,如果我以某种方式误导你.



5> Chris..:

我自己很好奇.阅读文档和理论答案都很好,但我喜欢用经验证据来平衡这些.

我有一个MySQL表(InnoDB),其中有5,607,997条记录.该表位于我自己的私有沙箱中,因此我知道内容是静态的,没有其他人使用该服务器.我认为这有效地消除了对性能的所有外部影响.我有一个带有auto_increment主键字段(Id)的表,我知道它永远不会为null,我将用于我的where子句测试(WHERE Id IS NOT NULL).

我在运行测试中看到的唯一其他可能的故障是缓存.第一次运行查询总是比使用相同索引的后续查询慢.我将在下面将其称为缓存Seeding调用.只是为了把它混合一点,我用一个where子句运行它,我知道无论任何数据都会评估为真(TRUE = TRUE).

这就是我的结果:

查询类型

      |  w/o WHERE          | where id is not null |  where true=true

计数()

      |  9 min 30.13 sec ++ | 6 min 16.68 sec ++   | 2 min 21.80 sec ++
      |  6 min 13.34 sec    | 1 min 36.02 sec      | 2 min 0.11 sec 
      |  6 min 10.06 se     | 1 min 33.47 sec      | 1 min 50.54 sec

COUNT(同上)

      |  5 min 59.87 sec    | 1 min 34.47 sec      | 2 min 3.96 sec 
      |  5 min 44.95 sec    | 1 min 13.09 sec      | 2 min 6.48 sec

COUNT(1)

      | 6 min 49.64 sec    | 2 min 0.80 sec       | 2 min 11.64 sec
      | 6 min 31.64 sec    | 1 min 41.19 sec      | 1 min 43.51 sec

++这被认为是缓存Seeding调用.预计比其他人慢.

我会说结果不言而喻.COUNT(Id)通常会与其他人区分开来.添加Where子句会大大减少访问时间,即使它是您知道将评估为true的子句.甜蜜点似乎是COUNT(Id)... WHERE Id不是NULL.

我很乐意看到其他人的结果,可能是小桌子或者不同领域的条款而不是你所计算的领域.我确定还有其他变化我没有考虑到.

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有