计数(*)与计数(1) - SQL Server


Answers

在SQL Server中,这些语句产生相同的计划。

与流行的观点相反,在甲骨文他们也是如此。

Oracle中的SYS_GUID()是相当计算量的函数。

在我的测试数据库中, t_even是一个包含1,000,000行的表

这个查询:

SELECT  COUNT(SYS_GUID())
FROM    t_even

运行48秒,因为函数需要评估每个返回的SYS_GUID() ,以确保它不是NULL

但是,这个查询:

SELECT  COUNT(*)
FROM    (
        SELECT  SYS_GUID()
        FROM    t_even
        )

运行时间为2秒,因为它甚至不尝试评估SYS_GUID() (尽管*是作为COUNT(*)参数)

Question

只是想知道你们中的任何一个人是否使用Count(1)不是Count(*)并且如果在性能上存在显着差异,或者这只是从过去的日子中提出的遗留习惯?

(特定数据库是SQL Server 2005




由于这个问题一再出现,这里还有一个答案。 我希望在这里为想要了解“最佳实践”的初学者添加一些内容。

SELECT COUNT(*) FROM something记录这是一件容易的事。

SELECT COUNT(1) FROM something检索每个记录1,并计数不为null的1,这实质上是对记录进行计数,只是更复杂。

话虽如此:好的dbms注意到第二个陈述会导致与第一个陈述相同的计数,并相应地重新解释它,因为不做不必要的工作。 所以通常这两种表述都会导致相同的执行计划并且花费相同的时间。

但从可读性的角度来看,您应该使用第一条语句。 你想计数记录,所以计数记录,而不是表达式。 仅当您想计算某些事情的非空发生时才使用COUNT(表达式)。




我希望优化器能够确保在奇怪边缘情况之外没有真正的区别。

与任何事情一样,唯一真正的方法是测量你的具体情况。

也就是说,我一直使用COUNT(*)




在SQL-92标准中, COUNT(*)具体表示“表达式的基数”(可以是基表,VIEW,派生表,CTE等)。

我猜想这个想法是COUNT(*)很容易解析。 使用任何其他表达式都需要解析器确保它不引用任何列( COUNT('a') ,其中a是文字, COUNT(a)其中a是列可以产生不同的结果)。

同样,熟悉SQL标准的人类编码人员可以轻松挑选出COUNT(*) ,这是处理多个供应商的SQL产品时的一项有用技能。

另外,在特殊情况下SELECT COUNT(*) FROM MyPersistedTable; ,这个想法是DBMS可能会为表的基数保存统计数据。

因此,因为COUNT(1)COUNT(*)在语义上是等价的,所以我使用COUNT(*)




轻松演示COUNT(*)与COUNT(<some col>) -

USE tempdb;
GO

IF OBJECT_ID( N'dbo.Blitzen', N'U') IS NOT NULL DROP TABLE dbo.Blitzen;
GO

CREATE TABLE dbo.Blitzen (ID INT NULL, Somelala CHAR(1) NULL);

INSERT dbo.Blitzen SELECT 1, 'A';
INSERT dbo.Blitzen SELECT NULL, NULL;
INSERT dbo.Blitzen SELECT NULL, 'A';
INSERT dbo.Blitzen SELECT 1, NULL;

SELECT COUNT(*), COUNT(1), COUNT(ID), COUNT(Somelala) FROM dbo.Blitzen;
GO

DROP TABLE dbo.Blitzen;
GO





Links