Запрос списка количества записей в каждой таблице в базе данных - PullRequest
173 голосов
/ 18 сентября 2009

Как перечислить количество строк каждой таблицы в базе данных. Некоторый эквивалент

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

Я выложу решение, но другие подходы приветствуются

Ответы [ 19 ]

273 голосов
/ 18 сентября 2009

Если вы используете 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.

89 голосов
/ 04 января 2013

Фрагмент, который я нашел в 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;
23 голосов
/ 18 сентября 2013

Чтобы получить эту информацию в SQL Management Studio, щелкните правой кнопкой мыши базу данных, затем выберите Отчеты -> Стандартные отчеты -> Использование диска по таблице.

8 голосов
/ 06 апреля 2015
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;
6 голосов
/ 18 сентября 2009

Как видно здесь, это вернет правильные значения, тогда как методы, использующие таблицы метаданных, будут возвращать только оценки.

    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
3 голосов
/ 21 мая 2015
sp_MSForEachTable 'DECLARE @t AS VARCHAR(MAX); 
SELECT @t = CAST(COUNT(1) as VARCHAR(MAX)) 
+ CHAR(9) + CHAR(9) + ''?'' FROM ? ; PRINT @t'
* +1001 * Выход:

enter image description here

2 голосов
/ 02 марта 2016

Самый быстрый способ найти количество строк всех таблиц в SQL Refreence (http://www.codeproject.com/Tips/811017/Fastest-way-to-find-row-count-of-all-tables-in-SQL)

SELECT T.name AS [TABLE NAME], I.rows AS [ROWCOUNT] 
    FROM   sys.tables AS T 
       INNER JOIN sys.sysindexes AS I ON T.object_id = I.id 
       AND I.indid < 2 
ORDER  BY I.rows DESC
2 голосов
/ 10 июля 2015

К счастью, студия управления SQL Server подсказывает вам, как это сделать. Сделай это,

  1. запустить трассировку SQL Server и открыть занятие, которое вы делаете (фильтр по вашему логину, если вы не одиноки и установите имя приложения в Microsoft SQL Server Management Studio), приостановить трассировку и отменить любые результаты, которые вы записали до сих пор;
  2. Затем щелкните правой кнопкой мыши таблицу и выберите свойство во всплывающем меню;
  3. начать трассировку снова;
  4. Теперь в SQL Server Management studio выберите элемент свойства хранилища слева;

Приостановите трассировку и посмотрите, что TSQL генерирует Microsoft.

В, вероятно, последнем запросе вы увидите оператор, начинающийся с 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-сервер, и он будет генерировать TSQL, который работает со всеми элементами, с которыми вы можете работать, используя версию на используемой вами SSMS, так что он довольно хорош для большого разнообразия выпусков. , настоящее и будущее.

И помните, не просто копируйте, постарайтесь понять это, иначе вы можете ошибиться.

Walter

1 голос
/ 18 сентября 2009

Первое, что пришло в голову, это использовать 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 голос
/ 28 октября 2017

Этот подход использует конкатенацию строк для динамического создания оператора со всеми таблицами и их количеством, как в примере (ах), приведенном в исходном вопросе:

          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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...