【问题标题】:T-SQL Stored Procedure: Performance of select count(*) vs. select count([uniqueId])T-SQL 存储过程:select count(*) 与 select count([uniqueId]) 的性能
【发布时间】:2015-12-18 12:50:43
【问题描述】:

所以,我在这里查看一个存储过程,它有不止一行,如以下伪代码:

if(select count(*) > 0)
...

在具有唯一 id(或标识符,以使其更通用)的表上。

现在,就性能而言,更改此子句是否更具性能 到

if(select count([uniqueId]) > 0)
    ...

uniqueId 在哪里,例如,包含双精度值的 Idx

一个例子:

考虑像 Idx (double) | 这样的表名称(字符串)|地址(字符串)

现在“Idx”是我想加入存储过程的外键。

那么,就性能而言:这里有什么更好的地方?

if(select count(*) > 0)
    ...

if(select count(Idx) > 0)
    ...

?还是 SQL 引擎在内部将 select count(*) 更改为 select count(Idx),所以我们不必为此烦恼?因为乍一看,我会说select count(Idx) 会更高效。

【问题讨论】:

  • 为了性能,请使用IF EXISTS (SELECT 1 FROM ...) 而不是计数。至于你的问题:查询优化器足够聪明,可以从COUNT(1) vs COUNT(*) vs COUNT(index)获得相同的最优计划
  • 啊,好的,谢谢!但尽管如此,我还是让这个问题开放,因为我对答案很感兴趣。
  • @lad2025 他们将生成相同的执行计划。所以 Dominik 使用你们提供或存在的任何一个。
  • @MartinSmith,有趣的链接,但他使用了我认为有影响的 where 子句?我已经检查了 4 个计数和存在的变体,它们产生了相同的计划和 IO。从 2007 年开始,该链接已经过时了。我认为从那时起优化器变得更聪明了?
  • @GiorgiNakeuri 我不确定可以应用优化的确切情况。我肯定会一直使用exists

标签: sql sql-server performance stored-procedures


【解决方案1】:

两者略有不同。 count(*) 计算行数。 count([uniqueid]) 计算 uniqueid 的非 NULL 值的数量。因为唯一约束允许NULL 值,SQL Server 实际上需要读取该列。这可能会为查询增加几微秒的时间,特别是如果带有id 的页面尚未在内存中。这也为 SQL Server 提供了更多优化count(*) 的机会。

正如@lad2025 在评论中所写,高效的解决方案是使用if (exists . . .

【讨论】:

    【解决方案2】:
    SELECT t1.* 
    FROM Table1 t1
    JOIN Table2 t2 ON t2.idx = t1.idx
    

    将只为您提供 t1 中与 Table2 中的 idx 值匹配的行。我不确定是否有充分的理由执行 if(select count...)。

    如果您真的对这样的性能感兴趣,只需创建一个包含一百万行的临时表并试一试:

    CREATE TABLE #TempTable (id int identity, txt varchar(50))
    GO
    
    INSERT #TempTable (txt) VALUES (@@IDENTITY)
    GO 1000000
    

    【讨论】:

    • If 是 TSQL 中的过程关键字。 OP 将使用它来处理结果集,例如整个表而不是单个行。并且没有迹象表明涉及第二个表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 2015-03-19
    相关资源
    最近更新 更多