데이터베이스의 각 테이블에있는 레코드 수를 나열하는 쿼리


196

데이터베이스에서 각 테이블의 행 수를 나열하는 방법 일부

select count(*) from table1
select count(*) from table2
...
select count(*) from tableN

나는 해결책을 게시 할 것이지만 다른 접근법은 환영합니다.

답변:


311

SQL Server 2005 이상을 사용하는 경우 다음을 사용할 수도 있습니다.

SELECT 
    t.NAME AS TableName,
    i.name as indexName,
    p.[Rows],
    sum(a.total_pages) as TotalPages, 
    sum(a.used_pages) as UsedPages, 
    sum(a.data_pages) as DataPages,
    (sum(a.total_pages) * 8) / 1024 as TotalSpaceMB, 
    (sum(a.used_pages) * 8) / 1024 as UsedSpaceMB, 
    (sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
    t.NAME NOT LIKE 'dt%' AND
    i.OBJECT_ID > 255 AND   
    i.index_id <= 1
GROUP BY 
    t.NAME, i.object_id, i.index_id, i.name, p.[Rows]
ORDER BY 
    object_name(i.object_id) 

제 생각에는 sp_msforeachtable출력 보다 처리하기가 더 쉽습니다 .


1
왜 "dt"로 시작하는 이름을 가진 테이블을 걸러 내는지 아십니까? 나는이 스크립트를 인터넷에서 보았지만 그 기준에 대한 설명은 없습니다. 우리 모두 트롤되고 있습니까?
Skaue

6
@Skaue : "데이터베이스 다이어그램"기능을 자신의 데이터베이스에 설치하면 다음과 같은 테이블이 있습니다 dtProperties. 그것들은 "시스템"테이블이기 때문에 나는 그것들에 대해보고하고 싶지 않습니다.
marc_s

1
이 스크립트에서 테이블 이름 앞에 스키마 이름을 추가 할 수 있습니까?
gh0st

어떤 이유로이 쿼리는 모든 테이블을 반환하지 않습니다. 데이터베이스에 382 개의 테이블이 있습니다. 그러나이 쿼리는 270 개의 행 (테이블 정보) 만 반환합니다. where 조건을 제거한 후 302 행이 표시됩니다. SYS 테이블 중 하나에서 일부 테이블 정보가 누락되어 조인이 테이블 정보를 생략했기 때문입니다. 데이터베이스에 시스템 테이블이 없습니다.
Ankesh Kushwah

작동합니다. 두 데이터베이스를 비교하도록 수정할 수 있습니다.
sanjeewa

107

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=21021 에서 찾은 스 니펫 은 다음과 같습니다.

select t.name TableName, i.rows Records
from sysobjects t, sysindexes i
where t.xtype = 'U' and i.id = t.id and i.indid in (0,1)
order by TableName;

5
나는이 솔루션을 좋아하지만 JOIN구문을 사용하지만from sysobjects t inner join sysindexes i on i.id = t.id and i.indid in (0,1) where t.xtype = 'U'
Shnugo

JOIN 문을 사용하는 것을 선호하지만 코드 스 니펫을 발견했을 때 게시했습니다. :)
Erik Anderson

32

SQL Management Studio에서 해당 정보를 얻으려면 데이터베이스를 마우스 오른쪽 단추로 클릭 한 후 보고서-> 표준 보고서-> 테이블 별 디스크 사용량을 선택하십시오.


6
과소 평가 된 접근 방식은 # 개의 행과 데이터 크기를 보여주는 정렬 가능한 보고서를 신속하게 생성합니다.
tbone

8
SELECT 
    T.NAME AS 'TABLE NAME',
    P.[ROWS] AS 'NO OF ROWS'
FROM SYS.TABLES T 
INNER JOIN  SYS.PARTITIONS P ON T.OBJECT_ID=P.OBJECT_ID;

3
이 쿼리는 모든 테이블의 각 인덱스에 대한 행 결과를 반환합니다. WHERE P.INDEX_ID IN (0,1)을 추가하여 리턴 결과 세트를 적절한 경우에만 힙 또는 클러스터 된 인덱스로 제한하십시오.
Rasmus Remmer Bielidt

6

여기에서 볼 수 있듯이 메타 데이터 테이블을 사용하는 메서드는 추정값 만 반환하는 올바른 카운트를 반환합니다.

    CREATE PROCEDURE ListTableRowCounts 
    AS 
    BEGIN 
        SET NOCOUNT ON 

        CREATE TABLE #TableCounts
        ( 
            TableName VARCHAR(500), 
            CountOf INT 
        ) 

        INSERT #TableCounts
            EXEC sp_msForEachTable 
                'SELECT PARSENAME(''?'', 1), 
                COUNT(*) FROM ? WITH (NOLOCK)' 

        SELECT TableName , CountOf 
            FROM #TableCounts
            ORDER BY TableName 

        DROP TABLE #TableCounts
    END
    GO

따라서 문서화되지 않은 stor proc sp_msForEachTable을 사용하는 것과 때로는 최신 정보가없는 시스템 테이블을 사용하는 것의 타협처럼 들립니다. 링크에 대한 +1 감사
크리스토프

3
sp_MSForEachTable 'DECLARE @t AS VARCHAR(MAX); 
SELECT @t = CAST(COUNT(1) as VARCHAR(MAX)) 
+ CHAR(9) + CHAR(9) + ''?'' FROM ? ; PRINT @t'

산출:

여기에 이미지 설명을 입력하십시오


Sql Server 2000에 필요한 것이 필요했습니다. 감사!
Alrekr

3

운 좋게도 SQL Server 관리 스튜디오는이를 수행하는 방법에 대한 힌트를 제공합니다. 이 작업을 수행,

  1. SQL Server 추적을 시작하고 수행중인 활동 (독립적이 아닌 경우 로그인 ID로 필터링하고 응용 프로그램 이름을 Microsoft SQL Server Management Studio로 설정)을 열고 추적을 일시 중지하고 지금까지 기록한 모든 결과를 삭제하십시오.
  2. 그런 다음 테이블을 마우스 오른쪽 버튼으로 클릭하고 팝업 메뉴에서 속성을 선택하십시오.
  3. 추적을 다시 시작하십시오.
  4. 이제 SQL Server Management Studio에서 왼쪽의 저장소 속성 항목을 선택하십시오.

추적을 일시 정지하고 Microsoft가 TSQL을 생성하는 것을 살펴보십시오.

아마도 마지막 쿼리에서 다음으로 시작하는 문장을 볼 수 있습니다 exec sp_executesql N'SELECT

실행 된 코드를 Visual Studio에 복사하면이 코드가 Microsoft 엔지니어가 속성 창을 채우는 데 사용하는 모든 데이터를 생성한다는 것을 알 수 있습니다.

해당 쿼리를 약간 수정하면 다음과 같은 결과가 나타납니다.

SELECT
SCHEMA_NAME(tbl.schema_id)+'.'+tbl.name as [table], --> something I added
p.partition_number AS [PartitionNumber],
prv.value AS [RightBoundaryValue],
 fg.name AS [FileGroupName],
CAST(pf.boundary_value_on_right AS int) AS [RangeType],
CAST(p.rows AS float) AS [RowCount],
p.data_compression AS [DataCompression]
FROM sys.tables AS tbl
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and idx.index_id < 2
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int) AND p.index_id=idx.index_id
LEFT OUTER JOIN sys.destination_data_spaces AS dds ON dds.partition_scheme_id = idx.data_space_id and dds.destination_id = p.partition_number
LEFT OUTER JOIN sys.partition_schemes AS ps ON ps.data_space_id = idx.data_space_id
LEFT OUTER JOIN sys.partition_range_values AS prv ON prv.boundary_id = p.partition_number and prv.function_id = ps.function_id
LEFT OUTER JOIN sys.filegroups AS fg ON fg.data_space_id = dds.data_space_id or fg.data_space_id = idx.data_space_id
LEFT OUTER JOIN sys.partition_functions AS pf ON  pf.function_id = prv.function_id

이제 쿼리가 완벽하지 않고 다른 질문에 맞게 업데이트 할 수 있습니다. 요점은 Microsoft에 대한 지식을 사용하여 관심있는 데이터를 실행하여 필요한 대부분의 질문에 도달 할 수 있다는 것입니다. 프로파일 러를 사용하여 생성 된 TSQL

MS 엔지니어가 SQL 서버의 작동 방식을 알고 있다고 생각하고 사용중인 SSMS의 버전을 사용하여 작업 할 수있는 모든 항목에서 작동하는 TSQL을 생성한다고 생각하고 싶습니다. 미래.

그리고 그냥 복사하지 말고 이해하려고 노력하십시오. 그렇지 않으면 잘못된 해결책으로 끝날 수 있습니다.

월터


2

이 접근법은 문자열 연결을 사용하여 원래 질문에 제공된 예제와 같이 모든 테이블과 해당 개수를 동적으로 갖는 명령문을 생성합니다.

          SELECT COUNT(*) AS Count,'[dbo].[tbl1]' AS TableName FROM [dbo].[tbl1]
UNION ALL SELECT COUNT(*) AS Count,'[dbo].[tbl2]' AS TableName FROM [dbo].[tbl2]
UNION ALL SELECT...

마지막으로 이것은 다음과 EXEC같이 실행됩니다 .

DECLARE @cmd VARCHAR(MAX)=STUFF(
                    (
                        SELECT 'UNION ALL SELECT COUNT(*) AS Count,''' 
                              + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME) 
                              + ''' AS TableName FROM ' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME)
                        FROM INFORMATION_SCHEMA.TABLES AS t
                        WHERE TABLE_TYPE='BASE TABLE'
                        FOR XML PATH('')
                    ),1,10,'');
EXEC(@cmd);

이 솔루션은 스키마의 이름 (유용 할 수있다)가 포함되어 있습니다
gordon613


1

가장 먼저 떠오른 것은 sp_msForEachTable을 사용하는 것이 었습니다.

exec sp_msforeachtable 'select count(*) from ?'

테이블 이름을 나열하지 않으므로 확장 할 수 있습니다.

exec sp_msforeachtable 'select parsename(''?'', 1),  count(*) from ?'

여기서 문제는 데이터베이스에 100 개가 넘는 테이블이있는 경우 다음 오류 메시지가 표시된다는 것입니다.

쿼리가 결과 표에 표시 될 수있는 최대 결과 집합 수를 초과했습니다. 처음 100 개의 결과 집합 만 표에 표시됩니다.

그래서 테이블 변수를 사용하여 결과를 저장했습니다.

declare @stats table (n sysname, c int)
insert into @stats
    exec sp_msforeachtable 'select parsename(''?'', 1),  count(*) from ?'
select 
    * 
from @stats
order by c desc

1

허용 대답은 푸른 SQL에 나를 위해 작동하지 않았다, 여기에 하나 가 슈퍼 빠른 그리고 내가 원하는 정확히 무엇을했다,했다 :

select t.name, s.row_count
from sys.tables t
join sys.dm_db_partition_stats s
  ON t.object_id = s.object_id
    and t.type_desc = 'USER_TABLE'
    and t.name not like '%dss%'
    and s.index_id = 1
order by s.row_count desc

1

이 SQL 스크립트는 선택된 데이터베이스에서 각 테이블의 스키마, 테이블 이름 및 행 수를 제공합니다.

SELECT SCHEMA_NAME(schema_id) AS [SchemaName],
[Tables].name AS [TableName],
SUM([Partitions].[rows]) AS [TotalRowCount]
FROM sys.tables AS [Tables]
JOIN sys.partitions AS [Partitions]
ON [Tables].[object_id] = [Partitions].[object_id]
AND [Partitions].index_id IN ( 0, 1 )
-- WHERE [Tables].name = N'name of the table'
GROUP BY SCHEMA_NAME(schema_id), [Tables].name
order by [TotalRowCount] desc

참조 : https://blog.sqlauthority.com/2017/05/24/sql-server-find-row-count-every-table-database-efficiently/

이를 수행하는 다른 방법 :

SELECT  o.NAME TABLENAME,
  i.rowcnt 
FROM sysindexes AS i
  INNER JOIN sysobjects AS o ON i.id = o.id 
WHERE i.indid < 2  AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
ORDER BY i.rowcnt desc

0

가장 짧고 빠르며 간단한 방법은 다음과 같습니다.

SELECT
    object_name(object_id) AS [Table],
    SUM(row_count) AS [Count]
FROM
    sys.dm_db_partition_stats
WHERE
    --object_schema_name(object_id) = 'dbo' AND 
    index_id < 2
GROUP BY
    object_id

0

당신은 이것을 시도 할 수 있습니다 :

SELECT  OBJECT_SCHEMA_NAME(ps.object_Id) AS [schemaname],
        OBJECT_NAME(ps.object_id) AS [tablename],
        row_count AS [rows]
FROM sys.dm_db_partition_stats ps
WHERE OBJECT_SCHEMA_NAME(ps.object_Id) <> 'sys' AND ps.index_id < 2
ORDER BY 
        OBJECT_SCHEMA_NAME(ps.object_Id),
        OBJECT_NAME(ps.object_id)

0
USE DatabaseName
CREATE TABLE #counts
(
    table_name varchar(255),
    row_count int
)

EXEC sp_MSForEachTable @command1='INSERT #counts (table_name, row_count) SELECT ''?'', COUNT(*) FROM ?'
SELECT table_name, row_count FROM #counts ORDER BY table_name, row_count DESC
DROP TABLE #counts

0

이 질문에서 : /dba/114958/list-all-tables-from-all-user-databases/230411#230411

모든 데이터베이스와 모든 테이블을 나열하는 @Aaron Bertrand가 제공 한 답변에 레코드 수를 추가했습니다.

DECLARE @src NVARCHAR(MAX), @sql NVARCHAR(MAX);

SELECT @sql = N'', @src = N' UNION ALL 
SELECT ''$d'' as ''database'', 
    s.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''schema'',
    t.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''table'' ,
    ind.rows as record_count
  FROM [$d].sys.schemas AS s
  INNER JOIN [$d].sys.tables AS t ON s.[schema_id] = t.[schema_id]
  INNER JOIN [$d].sys.sysindexes AS ind ON t.[object_id] = ind.[id]
  where ind.indid < 2';

SELECT @sql = @sql + REPLACE(@src, '$d', name)
  FROM sys.databases
  WHERE database_id > 4
    AND [state] = 0
    AND HAS_DBACCESS(name) = 1;

SET @sql = STUFF(@sql, 1, 10, CHAR(13) + CHAR(10));

PRINT @sql;
--EXEC sys.sp_executesql @sql;

0

이 코드 조각을 복사, 붙여 넣기 및 실행하여 모든 테이블 레코드 수를 테이블로 가져올 수 있습니다. 참고 : 코드는 지침으로 주석 처리됩니다

create procedure RowCountsPro
as
begin
--drop the table if exist on each exicution
IF OBJECT_ID (N'dbo.RowCounts', N'U') IS NOT NULL 
DROP TABLE dbo.RowCounts;
-- creating new table
CREATE TABLE RowCounts 
( [TableName]            VARCHAR(150)
, [RowCount]               INT
, [Reserved]                 NVARCHAR(50)
, [Data]                        NVARCHAR(50)
, [Index_Size]               NVARCHAR(50)
, [UnUsed]                   NVARCHAR(50))
--inserting all records
INSERT INTO RowCounts([TableName], [RowCount],[Reserved],[Data],[Index_Size],[UnUsed])
--  "sp_MSforeachtable" System Procedure, 'sp_spaceused "?"' param to get records and resources used
EXEC sp_MSforeachtable 'sp_spaceused "?"' 
-- selecting data and returning a table of data
SELECT [TableName], [RowCount],[Reserved],[Data],[Index_Size],[UnUsed]
FROM RowCounts
ORDER BY [TableName]
end

이 코드를 테스트했으며 SQL Server 2014에서 제대로 작동합니다.


0

나에게 효과가 있는 것을 공유하고 싶다

SELECT
      QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS [TableName]
      , SUM(sdmvPTNS.row_count) AS [RowCount]
FROM
      sys.objects AS sOBJ
      INNER JOIN sys.dm_db_partition_stats AS sdmvPTNS
            ON sOBJ.object_id = sdmvPTNS.object_id
WHERE 
      sOBJ.type = 'U'
      AND sOBJ.is_ms_shipped = 0x0
      AND sdmvPTNS.index_id < 2
GROUP BY
      sOBJ.schema_id
      , sOBJ.name
ORDER BY [TableName]
GO

데이터베이스는 Azure에서 호스팅되며 최종 결과는 다음과 같습니다. 여기에 이미지 설명을 입력하십시오

크레딧 : https://www.mssqltips.com/sqlservertip/2537/sql-server-row-count-for-all-tables-in-a-database/


-1

MySQL> 4.x를 사용하면 다음을 사용할 수 있습니다.

select TABLE_NAME, TABLE_ROWS from information_schema.TABLES where TABLE_SCHEMA="test";

일부 스토리지 엔진의 경우 TABLE_ROWS는 근사치입니다.


6
그는 마이크로 소프트 SQL 서버입니다 (태그)를 자신의 게시물에서 "SQL 서버"언급
marc_s을

-1
select T.object_id, T.name, I.indid, I.rows 
  from Sys.tables T 
  left join Sys.sysindexes I 
    on (I.id = T.object_id and (indid =1 or indid =0 ))
 where T.type='U'

여기서 indid=1클러스터 인덱스를 의미하고, indid=0힙이고


4
스택 오버플로에 오신 것을 환영합니다. 이 답변은 이미 1 년 전의 답변과 동일 합니다. 다시 게시 할 필요가 없습니다.
Ben
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.