【发布时间】:2019-03-11 22:14:53
【问题描述】:
我正在重写一个存储过程,该过程获取数据库中所有表的行数和最大值Id。该数据库有近 500 个表和超过 10 亿个条目,因此旧过程太慢而无法继续使用。
这是旧程序:
DECLARE @TableRowCounts TABLE ([TableName] VARCHAR(128), [RowCount] BIGINT, [MaxId] BIGINT) ;
INSERT INTO @TableRowCounts ([TableName], [RowCount], [MaxId])
EXEC sp_MSforeachtable 'SELECT ''?'' [TableName], COUNT(*) [RowCount], MAX(Id) [MaxId] FROM ?' ;
SELECT [TableName], [RowCount], [MaxId]
FROM @TableRowCounts
ORDER BY [TableName]
这将给出如下结果:
TableName | RowCount | MaxId
-------------------------------
TableA | 12345678 | 12345688
TableB | 90123456 | 90123466
TableC | 78901234 | 78901244
我不能说运行需要多长时间,因为我还没有真正观察到它在当前数据库的大小下完成。
这是一个正在进行中的新查询:
SELECT
o.NAME,
i.rowcnt
FROM sysindexes AS i
INNER JOIN sysobjects AS o ON i.id = o.id
--INNER JOIN sys.tables AS t ON t.[object_id] = o.id ???
--INNER JOIN sys.schemas AS s on t.[schema_id] = s.[schema_id] ???
--INNER JOIN sys.columns AS c on t.[object_id] = c.[object_id] ???
WHERE i.indid < 2 AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
ORDER BY o.NAME
我的想法是使用sys.schemas 和sys.columns,这样我就可以在我的SELECT 中使用MAX(Id),但我目前还停留在如何完全整合此功能上。如果有其他更好的方法可以做到这一点,我愿意接受建议。
我确实需要行数和MAX(Id)。我的数据集不应包含任何缺失的 Id,这将有助于一目了然地显示缺失的 Id。数据正在从外部源缓存,并且不应丢失任何 Id,因此如果行数不等于 MAX(Id),则使用数据库的客户端可以看到这一点并采取必要的措施来填充丢失的行。客户端还将行数和MAX(Id) 用于其他任务,例如将外部源的当前 ID 与数据库的最大 ID 进行比较。如果外部源的当前 Id 大于数据库的 MAX(Id),则有工作要做。
【问题讨论】:
-
请注意,但如果您的表曾经对它们运行过 DELETE,或者如果 Id 是 IDENTITY 列并且标识已被重新植入,则 MAX(Id) 不会为您提供正确的行数随时。您可能不是这种情况,但想指出这一点。
-
如果任何表中都不存在名称 ID 列怎么办?
-
试试这个来获取行数stackoverflow.com/a/2221898/10532500
-
@squillman 我明白这一点。对不起,如果我的措辞不清楚。我想要行数以及表的最大 id。
-
@SurajKumar 所有表都有相同的模式,所以
Id保证存在。感谢您提供链接,但我的新程序已经成功获取每个表的行数,而不是MAX(Id)
标签: sql-server tsql