如何统计已查询出的无主键数据表列表中各表的行数?
给无主键数据表添加行数统计的实现方法
你可以通过两种方式实现需求,一种是利用系统视图高效获取行数,另一种是通过动态SQL执行精确计数,具体如下:
方法一:利用系统视图高效统计(推荐)
通过关联sys.dm_db_partition_stats视图,它存储了SQL Server维护的表分区行数统计,无需全表扫描,效率很高。修改后的查询语句如下:
SELECT SCHEMA_NAME(tab.schema_id) AS schema_name, tab.name AS table_name, SUM(pst.row_count) AS row_count FROM sys.tables tab LEFT JOIN sys.indexes pk ON tab.object_id = pk.object_id AND pk.is_primary_key = 1 JOIN sys.dm_db_partition_stats pst ON tab.object_id = pst.object_id AND pst.index_id IN (0, 1) -- 覆盖堆表(无聚集索引)和有聚集索引的表 WHERE pk.object_id IS NULL GROUP BY SCHEMA_NAME(tab.schema_id), tab.name ORDER BY schema_name, table_name;
说明:
index_id IN (0,1):无主键的表可能是堆表(index_id=0),也可能存在自定义的聚集索引(index_id=1),这个条件能覆盖这两种情况SUM(pst.row_count):兼容分区表场景,单分区表直接取row_count也可,SUM更通用- 该方法的行数基于系统统计信息,若统计信息过时,结果可能有偏差,但速度远快于全表计数
方法二:动态SQL执行精确计数
如果需要完全精确的实时行数,可以用动态SQL生成每个表的COUNT(*)语句,适合小表或对精度要求极高的场景:
DECLARE @sql NVARCHAR(MAX) = N''; SELECT @sql += N' SELECT ''' + SCHEMA_NAME(tab.schema_id) + ''' AS schema_name, ''' + tab.name + ''' AS table_name, COUNT(*) AS row_count FROM ' + QUOTENAME(SCHEMA_NAME(tab.schema_id)) + '.' + QUOTENAME(tab.name) + ' UNION ALL' FROM sys.tables tab LEFT JOIN sys.indexes pk ON tab.object_id = pk.object_id AND pk.is_primary_key = 1 WHERE pk.object_id IS NULL; -- 移除末尾多余的UNION ALL SET @sql = LEFT(@sql, LEN(@sql) - 10); EXEC sp_executesql @sql;
说明:
- 该方法会对每个无主键表执行全表扫描,大表会显著消耗资源,谨慎使用
- 结果是实时精确的行数统计
内容的提问来源于stack exchange,提问作者Forgottenluv
相关产品推荐
相关产品推荐

