在数百万行上.. 是否值得缓存总量或关闭 NOCOUNT?而不是每次都请求那么多数据?
Sql Server 2008 R2
另外,是否仅在 Primary_Key 上运行 COUNT() 语句,以提高性能?
NOCOUNT 并不意味着“不计算”——它只是意味着“不报告计数”。报告可能会导致服务器和客户端之间出现大量不必要的聊天(通常会被忽略),并且可能会被某些 API 错误地解释为结果集。在我之前的工作中,我们的一项编码政策是在每个程序中都需要 SET NOCOUNT ON,我仍然将其作为最佳实践进行推广。然而,有一些 API 依赖于此消息,事实上,您自己的 .NET 代码今天可能依赖于 .RecordsAffected。
至于计数,您可以使用 sys.dm_db_partition_stats 但请注意,这并不能保证 100% 的准确性 - 就像使用 NOLOCK 进行直接计数一样,它不会考虑正在进行的事务。
我还建议对@garik 的回答进行一些改进:
SELECT
sch = OBJECT_SCHEMA_NAME(i),
obj = OBJECT_NAME(i),
[RowCount] = rc
FROM
(
SELECT
i = [object_id],
rc = SUM(row_count)
FROM sys.dm_db_partition_stats
WHERE index_id IN (0,1)
GROUP BY [object_id]
) AS x
ORDER BY [RowCount] DESC;
Run Code Online (Sandbox Code Playgroud)
这将考虑分区,包括架构和对象名称,并明确标识堆和聚集索引(谁知道 Microsoft 何时开始提供假设索引或其他系统定义的索引负 index_id 值)。
编辑:
至于关于依靠主键的问题,您将发现COUNT(*)
和之间的性能没有差异COUNT(key_column)
- 如果您检查计划,它们应该是相同的。但是,使用时要小心COUNT(nullable_column)
- 我个人认为COUNT(*)
更安全。也就是说,对于数百万行,获得 100% 准确计数的现实要求很少。从上面的 DMV 检索行数应该绰绰有余,并且不会影响表本身(或被表上的操作减慢)。