500+百万行表的主键列上的选择查询未响应

问题描述

我在SQL Server中有一个表,该表有500+百万行,并且在表的主键上定义了默认的聚集索引。我正在运行这个简单的查询,耗时超过30分钟。

Select count(ledgeridXXX) from Ledger.dbo.tblXXXX 

这是聚集索引定义的一部分

CONSTRAINT [PK__tblDepar__AE70E0AFF9BAF7B9] PRIMARY KEY CLUSTERED 
(
    [LedgerIDXXX] ASC
) 
WITH (PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]

我不知道哪里可能出错,为什么花那么多时间。请提出一些修复方法,因为这是关键表,主要报告在很大程度上依赖于此表。

解决方法

如果您只是在计算行数,则可以尝试以下操作:

SELECT SUM(p.rows) as [cnt]
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 t.[schema_id] = s.[schema_id]
WHERE p.index_id = 1 /* clustered index */
AND t.name = N'tblXXXX'AND s.name = N'dbo';

COUNT(clusteredkey)可能会在您的工作量很大时产生一些开销。扫描整个5亿行可能要花几个小时。

如果您正在运行更高版本的SQL Server,则可以使用列存储索引来加快COUNT的速度。

参考:

  1. Bad habits - Count The Hard Way
  2. Fast count - Stackoverflow
  3. Columnstore Index Fast Count
,

在没有COUNT(Column)子句的情况下执行COUNT(1)COUNT(*)where会发生什么:

SQL Server查找将完成此工作的最小索引(在单个AK页中包含最少的列,最多的行)。

如果仅具有聚集索引,则意味着它将使用聚集索引。 (聚集索引包含表的所有列)

您可以采取哪些措施来加快速度:

  1. 创建仅具有1列的单独索引,最好是小数据类型。 (创建索引可能要花费很多时间。)
  2. 为查询创建索引视图。由于您没有分组,因此我不建议您这样做。
  3. 指定表提示WITH(TABLOCK)WITH(TABLOCKX)强制表锁定或排他表锁定。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...