只是想知道你们中是否有人使用Count(1)而不是Count(*),是否在性能上有明显的差异,或者这只是过去几天养成的传统习惯?
特定的数据库是SQL Server 2005。
只是想知道你们中是否有人使用Count(1)而不是Count(*),是否在性能上有明显的差异,或者这只是过去几天养成的传统习惯?
特定的数据库是SQL Server 2005。
当前回答
在所有RDBMS中,这两种计数方式在产生什么结果方面是等价的。关于性能,我没有在SQL Server中观察到任何性能差异,但值得指出的是,一些RDBMS,例如PostgreSQL 11,在检查参数表达式的可空性时,COUNT(1)的实现不太理想,如本文所示。
我发现运行以下命令时,1M行的性能差异为10%:
-- Faster
SELECT COUNT(*) FROM t;
-- 10% slower
SELECT COUNT(1) FROM t;
其他回答
SET STATISTICS TIME ON
select count(1) from MyTable (nolock) -- table containing 1 million records.
SQL Server执行时间:CPU时间=31ms,经过时间=36ms。
select count(*) from MyTable (nolock) -- table containing 1 million records.
SQL Server执行时间:CPU时间=46 ms,经过时间=37 ms。
我已经运行了数百次,每次都清除缓存。。结果随服务器负载的变化而变化,但几乎总是count(*)具有较高的cpu时间。
COUNT(*)和COUNT(1)在结果和性能方面是相同的。
没有区别。
原因:
在线书籍说“COUNT({[[ALL|DISTINCT]expression]|*})”
“1”是非空表达式:因此它与COUNT(*)相同。优化器识别它的本质:微不足道。
与EXISTS相同(SELECT*…或EXISTS(SELECT 1。。。
例子:
SELECT COUNT(1) FROM dbo.tab800krows
SELECT COUNT(1),FKID FROM dbo.tab800krows GROUP BY FKID
SELECT COUNT(*) FROM dbo.tab800krows
SELECT COUNT(*),FKID FROM dbo.tab800krows GROUP BY FKID
相同的IO,相同的计划,工作
编辑,2011年8月
DBA.SE上的类似问题。
编辑,2011年12月
ANSI-92中特别提到了COUNT(*)(查找“标量表达式125”)
案例:a) 如果指定了COUNT(*),则结果是T的基数。
也就是说,ANSI标准认为这是你的意思。由于这种迷信,RDBMS供应商已经优化了COUNT(1)。否则将按照ANSI进行评估
b) 否则,让TX是单列表,即将<value表达式>应用于T的每一行的结果以及消除空值。如果一个或多个空值消除,则引发完成条件:警告-
COUNT(1)与COUNT。关于计数空列的问题,这可以直接演示COUNT(*)和COUNT之间的差异(<somecol>)--
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
我在一个8GB的RAM超级存储箱上对SQL Server 2012进行了快速测试。您可以自己查看结果。在运行这些测试时,我没有运行除SQLServerManagementStudio之外的任何其他窗口应用程序。
我的表架构:
CREATE TABLE [dbo].[employee](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_employee] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
雇员表中的记录总数:178090131(约1.78亿行)
第一个查询:
Set Statistics Time On
Go
Select Count(*) From Employee
Go
Set Statistics Time Off
Go
第一次查询的结果:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 35 ms.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 10766 ms, elapsed time = 70265 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
第二个查询:
Set Statistics Time On
Go
Select Count(1) From Employee
Go
Set Statistics Time Off
Go
第二次查询的结果:
SQL Server parse and compile time:
CPU time = 14 ms, elapsed time = 14 ms.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 11031 ms, elapsed time = 70182 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
您可以注意到有83(=70265-70182)毫秒的差异,这很容易归因于运行查询时的确切系统条件。我也做了一次跑步,所以如果我做了几次跑步并做了一些平均,这种差异会变得更准确。如果对于如此庞大的数据集,差异小于100毫秒,那么我们可以很容易地得出结论,这两个查询没有SQL Server引擎表现出的任何性能差异。
注意:在两次运行中,RAM的使用率接近100%。在开始两次运行之前,我重新启动了SQL Server服务。