Kueri untuk mendaftar jumlah rekaman di setiap tabel dalam database


198

Cara daftar jumlah baris setiap tabel dalam database. Beberapa setara dengan

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

Saya akan memposting solusi tetapi pendekatan lain dipersilakan

Jawaban:


313

Jika Anda menggunakan SQL Server 2005 dan lebih tinggi, Anda juga dapat menggunakan ini:

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) 

Menurut pendapat saya, lebih mudah ditangani daripada sp_msforeachtableoutput.


1
Adakah yang tahu mengapa ini memfilter tabel dengan nama yang dimulai dengan "dt"? Saya telah melihat skrip ini di seluruh internet, tetapi tidak ada penjelasan tentang kriteria itu. Apakah kita semua dikendalikan?
Skaue

6
@ Skaue: jika Anda menginstal fungsionalitas "Diagram Database" ke dalam database Anda, maka Anda akan memiliki beberapa tabel seperti dtPropertiesdan seterusnya; karena itu adalah tabel "sistem", saya tidak ingin melaporkannya.
marc_s

1
Kemungkinan prefixing tablename dengan nama skema dalam skrip ini?
gh0st

Untuk beberapa alasan, kueri ini tidak mengembalikan semua tabel. Saya punya 382 tabel dalam database. Tetapi kueri ini hanya mengembalikan 270 baris (informasi tabel). Setelah menghapus kondisi di mana saya mendapatkan 302 baris. Apakah karena fakta bahwa beberapa informasi tabel hilang dari salah satu tabel SYS sehingga bergabung menghilangkannya. Basis data tidak mengandung tabel sistem apa pun.
Ankesh Kushwah

Ini bekerja dapatkah Anda memodifikasinya untuk membandingkan dua database.
sanjeewa

107

Cuplikan yang saya temukan di http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=21021 yang membantu saya:

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
Saya suka solusi ini, walaupun saya akan menggunakan JOINsintaksfrom sysobjects t inner join sysindexes i on i.id = t.id and i.indid in (0,1) where t.xtype = 'U'
Shnugo

Saya lebih suka menggunakan pernyataan GABUNG juga tetapi memposting potongan kode ketika saya menemukannya. :)
Erik Anderson

32

Untuk mendapatkan informasi itu di SQL Management Studio, klik kanan pada database, lalu pilih Laporan -> Laporan Standar -> Penggunaan Disk berdasarkan Tabel.


6
Pendekatan yang diremehkan, ini dengan cepat menghasilkan laporan yang dapat diurutkan yang menunjukkan # baris dan ukuran data.
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
Kueri ini akan mengembalikan hasil baris untuk setiap indeks di setiap tabel. Tambahkan WHERE P.INDEX_ID IN (0,1) untuk membatasi hasil pengembalian yang disetel ke tumpukan atau indeks yang dikelompokkan hanya jika sesuai.
Rasmus Remmer Bielidt

6

Seperti yang terlihat di sini, ini akan mengembalikan jumlah yang benar, di mana metode menggunakan tabel data meta hanya akan mengembalikan perkiraan.

    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

Jadi kedengarannya seperti kompromi menggunakan sp_msForEachTable vs proc penyimpanan tidak berdokumen vs menggunakan tabel sistem dengan informasi info terkadang tidak paling mutakhir. +1 dan terima kasih atas tautannya
kristof

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

Keluaran:

masukkan deskripsi gambar di sini


Saya membutuhkan sesuatu untuk Sql Server 2000. Ini berhasil. Terima kasih!
Alrekr

3

Untungnya, studio manajemen SQL Server memberi Anda petunjuk tentang cara melakukan ini. Melakukan hal ini,

  1. mulai jejak SQL Server dan buka aktivitas yang Anda lakukan (filter dengan ID login Anda jika Anda tidak sendirian dan atur Nama aplikasi ke Microsoft SQL Server Management Studio), jeda jejak dan buang semua hasil yang telah Anda rekam sampai sekarang;
  2. Kemudian, klik kanan tabel dan pilih properti dari menu pop up;
  3. mulai jejak lagi;
  4. Sekarang di SQL Server Management studio pilih item properti penyimpanan di sebelah kiri;

Hentikan jejak dan lihat TSQL apa yang dihasilkan oleh microsoft.

Dalam kueri yang mungkin terakhir, Anda akan melihat pernyataan yang dimulai dengan exec sp_executesql N'SELECT

ketika Anda menyalin kode yang dieksekusi ke visual studio Anda akan melihat bahwa kode ini menghasilkan semua data yang digunakan para insinyur di microsoft untuk mengisi jendela properti.

ketika Anda membuat modifikasi moderat untuk permintaan itu, Anda akan mendapatkan sesuatu seperti ini:

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

Sekarang kueri tidak sempurna dan Anda dapat memperbaruinya untuk memenuhi pertanyaan lain yang mungkin Anda miliki, intinya adalah, Anda dapat menggunakan pengetahuan microsoft untuk mendapatkan sebagian besar pertanyaan yang Anda miliki dengan mengeksekusi data yang Anda minati dan melacak TSQL dihasilkan menggunakan profiler.

Saya agak suka berpikir bahwa insinyur MS tahu cara kerja server SQL dan, itu akan menghasilkan TSQL yang bekerja pada semua item yang Anda dapat bekerja dengan menggunakan versi pada SSMS yang Anda gunakan sehingga cukup baik pada berbagai rilis besar sebelum peluncuran, saat ini dan masa depan.

Dan ingat, jangan hanya menyalin, cobalah untuk memahaminya juga kalau tidak, Anda mungkin berakhir dengan solusi yang salah.

Walter


2

Pendekatan ini menggunakan penggabungan string untuk menghasilkan pernyataan dengan semua tabel dan perhitungannya secara dinamis, seperti contoh yang diberikan dalam pertanyaan awal:

          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...

Akhirnya ini dijalankan dengan 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);

perhatikan bahwa solusi ini mencakup nama skema (yang dapat berguna)
gordon613


1

Hal pertama yang terlintas dalam pikiran adalah menggunakan sp_msForEachTable

exec sp_msforeachtable 'select count(*) from ?'

itu tidak mencantumkan nama tabel, sehingga bisa diperluas ke

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

Masalahnya di sini adalah bahwa jika database memiliki lebih dari 100 tabel, Anda akan mendapatkan pesan kesalahan berikut:

Kueri telah melampaui jumlah set hasil maksimum yang dapat ditampilkan di kotak hasil. Hanya 100 set hasil pertama yang ditampilkan dalam kisi.

Jadi saya akhirnya menggunakan variabel tabel untuk menyimpan hasilnya

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

Jawaban yang diterima tidak berfungsi untuk saya di Azure SQL, ini salah satu yang melakukan, itu super cepat dan melakukan apa yang saya inginkan:

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

Skrip sql ini memberikan skema, nama tabel, dan jumlah baris setiap tabel dalam database yang dipilih:

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

Ref: https://blog.sqlauthority.com/2017/05/24/sql-server-find-row-count-every-table-database-efisienly/

Cara lain untuk melakukan ini:

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

Saya pikir cara tersingkat, tercepat dan paling sederhana adalah:

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

Anda bisa mencoba ini:

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

Dari pertanyaan ini: /dba/114958/list-all-tables-from-all-user-databases/230411#230411

Saya menambahkan jumlah catatan ke jawaban yang diberikan oleh @Aaron Bertrand yang mencantumkan semua database dan semua tabel.

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

Anda bisa menyalin, melewati dan mengeksekusi potongan kode ini untuk mendapatkan semua jumlah catatan tabel ke dalam tabel. Catatan: Kode dikomentari dengan instruksi

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

Saya telah menguji kode ini dan berfungsi baik di SQL Server 2014.


0

Saya ingin berbagi apa yang berfungsi untuk saya

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

Basis data di-host di Azure dan hasil akhirnya adalah: masukkan deskripsi gambar di sini

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


-1

Jika Anda menggunakan MySQL> 4.x Anda dapat menggunakan ini:

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

Perlu diingat bahwa untuk beberapa mesin penyimpanan, TABLE_ROWS adalah perkiraan.


6
ia menyebutkan "sql-server" dalam jabatannya (sebagai tag) yang merupakan Microsoft SQL Server
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'

Di sini indid=1berarti indeks CLUSTERED dan indid=0HEAP


4
Hai dan selamat datang di Stack Overflow. Jawaban ini identik dengan yang sudah berumur satu tahun ... tidak perlu mempostingnya lagi.
Ben
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.