SQL Server的计数速度较慢。

21 浏览
0 Comments

SQL Server的计数速度较慢。

计算数据量较大的表格可能非常慢,有时需要几分钟; 它还可能在繁忙的服务器上生成死锁。我想要显示实际值,NOLOCK不是一个选项。

我使用的服务器是SQL Server 2005或2008 Standard或Enterprise - 如果有关系的话。

我可以想象SQL Server维护每个表的计数,如果没有WHERE子句,我可以很快得到那个数字,对吗?

例如:

SELECT COUNT(*) FROM myTable

应立即返回正确的值。我需要依赖统计信息进行更新吗?

admin 更改状态以发布 2023年5月21日
0
0 Comments

(“大量的数据”有多大?-或许下面的执行操作已经帮助你了)

如果我在一个静态表上进行查询(表示很长一段时间内没有其他人会通过读/写/更新数据来干扰),该表有两亿行,并在我的开发机器(Oracle)上15秒内计算出 COUNT(*)。
考虑到数据的纯数量,这仍然相当快(至少在我的看法中)

正如你所说,NOLOCK不是一个选项,你可以考虑

exec sp_spaceused 'myTable'

同时也可以得到类似 NOLOCK 的效果(忽略争用和删除/更新操作等)

0
0 Comments

非常近似(忽略任何在飞行中的交易)的结果将会是:

SELECT SUM(p.rows) FROM sys.partitions AS p
  INNER JOIN sys.tables AS t
  ON p.[object_id] = t.[object_id]
  INNER JOIN sys.schemas AS s
  ON s.[schema_id] = t.[schema_id]
  WHERE t.name = N'myTable'
  AND s.name = N'dbo'
  AND p.index_id IN (0,1);

。这种方法会比 COUNT(*) 快得多,如果您的表正在快速地更改,这种方法并不一定不够准确-如果在您开始计算 COUNT 的时候(并且锁已经被获取),表已经更改,而当它返回时(锁已被释放,所有等待的写入事务现在可以写入表中),它是否更有价值?我不这么认为。如果您有一些要计算的表的子集(比如 WHERE some_column IS NULL),您可以在该列上创建一个过滤索引,并根据情况配置 where 子句(根据过滤索引创建较小的集合)。所以这两种索引之一:

CREATE INDEX IAmTheException ON dbo.table(some_column)
  WHERE some_column IS NULL;
CREATE INDEX IAmTheRule ON dbo.table(some_column)
  WHERE some_column IS NOT NULL;

然后,您可以使用类似的方式来获取计数:

SELECT SUM(p.rows) FROM sys.partitions AS p
  INNER JOIN sys.tables AS t
  ON p.[object_id] = t.[object_id]
  INNER JOIN sys.schemas AS s
  ON s.[schema_id] = t.[schema_id]
  INNER JOIN sys.indexes AS i
  ON p.index_id = i.index_id
  WHERE t.name = N'myTable'
  AND s.name = N'dbo'
  AND i.name = N'IAmTheException' -- or N'IAmTheRule'
  AND p.index_id IN (0,1);

如果您想知道相反的情况,您只需要从上述第一个查询中减去即可。

0