Самый быстрый способ подсчета точного количества строк в очень большой таблице? - PullRequest
217 голосов
/ 20 мая 2011

Я встречал статьи, в которых утверждается, что SELECT COUNT(*) FROM TABLE_NAME будет медленным, когда в таблице много строк и много столбцов.

У меня есть таблица, которая может содержать даже миллиарды строк [в ней приблизительно 15 столбцов]. Есть ли лучший способ получить число EXACT количества строк в таблице?

Пожалуйста, примите во внимание следующее перед ответом:

  • Ищу поставщика базы данных независимое решение. Это нормально, если это охватывает MySQL , Oracle , MS SQL Server . Но если действительно нет базы данных независимое от поставщика решение, то я соглашусь на разные решения для разных поставщиков баз данных.

  • Я не могу использовать любой другой внешний инструмент сделать это. Я в основном ищу Решение на основе SQL.

  • Я не могу нормализовать дизайн моей базы данных дальше Это уже в 3NF и более того много кода уже написано вокруг него.

Ответы [ 25 ]

228 голосов
/ 20 мая 2011

Простой ответ:

  • Независимое решение поставщика базы данных = использовать стандарт = COUNT(*)
  • Есть приблизительный SQL Serverрешения, но не использовать COUNT (*) = вне области

Примечания:

COUNT (1) = COUNT (*) =COUNT (PrimaryKey) на всякий случай

Редактировать:

Пример SQL Server (1,4 миллиарда строк, 12 столбцов)

SELECT COUNT(*) FROM MyBigtable WITH (NOLOCK)
-- NOLOCK here is for me only to let me test for this answer: no more, no less

1 прогон, 5:46 минут, счет = 1 401 659 700

--Note, sp_spaceused uses this DMV
SELECT
   Total_Rows= SUM(st.row_count)
FROM
   sys.dm_db_partition_stats st
WHERE
    object_name(object_id) = 'MyBigtable' AND (index_id < 2)

2 прогона, оба менее 1 секунды, счет = 1 401 659 670

Во втором из них меньше строк = неправильно.Будет одинаковым или более в зависимости от записи (удаление выполняется в нерабочее время)

25 голосов
/ 26 марта 2012

Самый быстрый способ на MySQL - это:

SHOW TABLE STATUS;

Вы мгновенно получите все свои таблицы с количеством строк (которое является общим) вместе с большим количеством дополнительной информации, если хотите.

10 голосов
/ 20 мая 2011

Я сталкивался со статьями, в которых утверждается, что SELECT COUNT (*) FROM TABLE_NAME будет медленным, когда в таблице много строк и много столбцов.

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

Обратите внимание, что вы обычно можете извлечь хорошую оценку, используя инструменты оптимизации запросов, статистику таблиц и т. Д. Например, в случае PostgreSQL вы можете проанализировать вывод explain count(*) from yourtable и получить достаточно хорошую оценку числа. рядов. Что подводит меня ко второму вопросу.

У меня есть таблица, которая может содержать даже миллиарды строк [в ней приблизительно 15 столбцов]. Есть ли лучший способ получить точный счетчик количества строк в таблице?

Серьезно? :-) Вы действительно имеете в виду счет точный из таблицы с миллиардами строк? Вы действительно уверены? : -)

Если вы действительно делаете, вы можете отслеживать общий итог, используя триггеры, но помните о параллелизме и взаимоблокировках, если вы это делаете.

9 голосов
/ 20 мая 2011

Вы можете попробовать это sp_spaceused (Transact-SQL)

Показывает количество строк, диск зарезервированное пространство и дисковое пространство таблица, индексированное представление или служба Брокерская очередь в текущей базе данных, или отображает зарезервированное место на диске и используется всей базой данных.

9 голосов
/ 26 мая 2011

Есть ли лучший способ получить точное значение количества строк в таблице?

Чтобы ответить на ваш вопрос просто, Нет .

Если вам нужен независимый от СУБД способ сделать это, самый быстрый способ всегда будет:

SELECT COUNT(*) FROM TableName

У некоторых поставщиков СУБД могут быть более быстрые способы, которые будут работать только для их систем. Некоторые из этих вариантов уже опубликованы в других ответах.

COUNT(*) все равно следует оптимизировать СУБД (по крайней мере, любую БД, достойную PROD), поэтому не пытайтесь обойти их оптимизацию.

На примечании стороны:
Я уверен, что многие другие ваши запросы также занимают много времени из-за размера таблицы. Любые проблемы с производительностью, вероятно, следует решать, думая о дизайне схемы с учетом скорости. Я понимаю, что вы сказали, что это не вариант для изменения, но может оказаться, что 10-минутные запросы тоже не вариант. 3-я NF - не всегда лучший подход, когда вам нужна скорость, и иногда данные могут быть разделены на несколько таблиц, если записи не имеют для совместного хранения. Есть о чем подумать ...

5 голосов
/ 30 июня 2013

Я далеко не такой эксперт, как другие, кто ответил, но у меня возникла проблема с процедурой, которую я использовал для выбора случайной строки из таблицы (не слишком релевантной), но мне нужно было знать количество строкмоя справочная таблица для расчета случайного индекса.Используя традиционную работу Count (*) или Count (1), но я иногда получал до 2 секунд для выполнения моего запроса.Поэтому вместо этого (для моей таблицы с именем 'tbl_HighOrder') я использую:

Declare @max int

Select @max = Row_Count
From sys.dm_db_partition_stats
Where Object_Name(Object_Id) = 'tbl_HighOrder'

Это прекрасно работает, и время запросов в Management Studio равно нулю.

5 голосов
/ 03 июля 2011

Я использую

select /*+ parallel(a) */  count(1) from table_name a;
5 голосов
/ 19 мая 2016

Хорошо, опоздал на 5 лет и не уверен, поможет ли это:

Я пытался сосчитать нет.строк в таблице SQL Server с использованием MS SQL Server Management Studio и столкнулся с некоторой ошибкой переполнения, затем я использовал следующее:

выберите count_big (1) ОТ[dbname]. [dbo]. [FactSampleValue];

Результат:

24296650578 строк

4 голосов
/ 20 мая 2011

Если выпуск SQL Server 2005/2008, вы можете использовать DMV для вычисления количества строк в таблице:

-- Shows all user tables and row counts for the current database 
-- Remove is_ms_shipped = 0 check to include system objects 
-- i.index_id < 2 indicates clustered index (1) or hash table (0) 
SELECT o.name, 
 ddps.row_count 
FROM sys.indexes AS i 
 INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID 
 INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID 
 AND i.index_id = ddps.index_id 
WHERE i.index_id < 2 
 AND o.is_ms_shipped = 0 
ORDER BY o.NAME 

Для ядра базы данных SQL Server 2000 будут работать sysindexes, но это настоятельно рекомендуетсячтобы не использовать его в будущих выпусках SQL Server, так как он может быть удален в ближайшем будущем.

Пример кода взят из: Как быстро и безболезненно подсчитать количество строк в таблице

3 голосов
/ 06 апреля 2018

Я нашел эту хорошую статью SQL Server - HOW-TO: быстро получить точное количество строк для таблицы из martijnh1, что дает хороший обзор для каждого сценария.

Мне это нужночтобы быть расширенным, где мне нужно предоставить счет на основе конкретного условия, и когда я придумаю эту часть, я обновлю этот ответ дальше.

А пока вот подробности из статьи:

Метод 1:

Запрос:

SELECT COUNT(*) FROM Transactions 

Комментарии:

Выполняетсяполное сканирование таблицы.Медленно на больших столах.

Метод 2:

Запрос:

SELECT CONVERT(bigint, rows) 
FROM sysindexes 
WHERE id = OBJECT_ID('Transactions') 
AND indid < 2 

Комментарии:

Быстрый способ получить количество строк.Зависит от статистики и неточно.

Запустите DBCC UPDATEUSAGE (База данных) с COUNT_ROWS, что может занять значительное время для больших таблиц.

Метод 3:

Запрос:

SELECT CAST(p.rows AS float) 
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 
WHERE ((tbl.name=N'Transactions' 
AND SCHEMA_NAME(tbl.schema_id)='dbo')) 

Комментарии:

Способ, которым студия управления SQL подсчитывает строки (посмотрите на свойства таблицы, хранилище, количество строк).Очень быстро, но все же приблизительное количество строк.

Метод 4:

Запрос:

SELECT SUM (row_count) 
FROM sys.dm_db_partition_stats 
WHERE object_id=OBJECT_ID('Transactions')    
AND (index_id=0 or index_id=1); 

Комментарии:

Быстрая (хотя и не такая быстрая, как метод 2) операция и, что не менее важно, надежная.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...