我知道做这样的查询通常是一个坏主意:
SELECT * FROM `group_relations`
但是,当我只想要计数时,我是否应该进行此查询,因为这样可以更改表但仍会产生相同的结果.
SELECT COUNT(*) FROM `group_relations`
或者更具特色
SELECT COUNT(`group_id`) FROM `group_relations`
我觉得后者可能会更快,但还有其他事情需要考虑吗?
更新:我在这种情况下使用InnoDB,抱歉没有更具体.
如果相关列是NOT NULL,则两个查询都是等效的.当group_id包含空值时
select count(*)
将计算所有行,而
select count(group_id)
将仅计算group_id不为null的行.
此外,某些数据库系统(如MySQL)会在您请求count(*)时使用优化,这使得此类查询比特定查询快一点.
就个人而言,在计算时,我正在使用空值来计算(*)以确保安全.
如果我没记错,在MYSQL COUNT(*)中计算所有行,而COUNT(column_name)只计算给定列中具有非NULL值的行.
COUNT(*)计算所有行,而COUNT(column_name)将仅计算指定列中没有NULL值的行.
在MySQL中需要注意的重要事项
对于*或非空列,COUNT()在MyISAM表上非常快,因为行计数被缓存.InnoDB没有行计数缓存,因此COUNT(*)或COUNT(column_name)的性能没有差异,无论该列是否为null.您可以在MySQL性能博客上阅读有关此帖子差异的更多信息.
如果您尝试SELECT COUNT(1) FROM
group_relations它会更快一些,因为它不会尝试从列中检索信息.
编辑:我刚做了一些研究,发现这只发生在一些数据库中.在sqlserver中使用1或*是一样的,但在oracle上使用1会更快.
http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/9367c580-087a-4fc1-bf88-91a51a4ee018/
显然,它们在mysql中没有区别,就像sqlserver一样,解析器似乎将查询更改为select(1).对不起,如果我以某种方式误导你.
我自己很好奇.阅读文档和理论答案都很好,但我喜欢用经验证据来平衡这些.
我有一个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.
我很乐意看到其他人的结果,可能是小桌子或者不同领域的条款而不是你所计算的领域.我确定还有其他变化我没有考虑到.