Получить количество записей для всех таблиц в базе данных MySQL

246

Есть ли способ получить количество строк во всех таблицах в базе данных MySQL без запуска SELECT count() в каждой таблице?

  • 1
    Расширенный ответ, который также точен для InnoDB: stackoverflow.com/questions/24707814/…
  • 1
    SELECT count (table_name) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'YOUR_DB' даст количество таблиц в вашей базе данных
Теги:

16 ответов

284
Лучший ответ
SELECT SUM(TABLE_ROWS) 
     FROM INFORMATION_SCHEMA.TABLES 
     WHERE TABLE_SCHEMA = '{your_db}';

Примечание из документов: Для таблиц InnoDB количество строк - это приблизительная оценка, используемая в SQL оптимизация. Вам нужно использовать COUNT (*) для точного подсчета (что более дорого).

  • 234
    или, если вы хотите для каждой таблицы: SELECT table_name, TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}';
  • 3
    Есть ли другой способ получить table_row и table_name? Потому что я хочу точный результат, а не грубую оценку. Спасибо.
Показать ещё 6 комментариев
128

Вероятно, вы можете добавить что-то вместе с Таблица таблиц. Я никогда не делал этого, но похоже, что у него есть столбец для TABLE_ROWS и один для TABLE NAME.

Чтобы получить строки в таблице, вы можете использовать такой запрос:

SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '**YOUR SCHEMA**';
  • 4
    Есть ли другой способ получить table_row и table_name? Потому что я хочу точный результат, а не грубую оценку. Спасибо.
  • 1
    как упомянул kuranl, это возвращает только оценку и, вероятно, даст несколько других результатов при запуске несколько раз
Показать ещё 2 комментария
74

Как и @Venkatramanan и другие, я обнаружил, что INFORMATION_SCHEMA.TABLES ненадежны (используя InnoDB, MySQL 5.1.44), давая разные подсчеты строк каждый раз, когда я запускаю его даже в пошаговых таблицах. Здесь относительно хакерский (но гибкий/адаптируемый) способ генерации большого оператора SQL, который вы можете вставить в новый запрос, не устанавливая камни Ruby и прочее.

SELECT CONCAT(
    'SELECT "', 
    table_name, 
    '" AS table_name, COUNT(*) AS exact_row_count FROM `', 
    table_schema,
    '`.`',
    table_name, 
    '` UNION '
) 
FROM INFORMATION_SCHEMA.TABLES 
WHERE table_schema = '**my_schema**';

Он производит вывод следующим образом:

SELECT "func" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.func UNION                         
SELECT "general_log" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.general_log UNION           
SELECT "help_category" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.help_category UNION       
SELECT "help_keyword" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.help_keyword UNION         
SELECT "help_relation" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.help_relation UNION       
SELECT "help_topic" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.help_topic UNION             
SELECT "host" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.host UNION                         
SELECT "ndb_binlog_index" AS table_name, COUNT(*) AS exact_row_count FROM my_schema.ndb_binlog_index UNION 

Скопируйте и вставьте, за исключением последнего UNION, чтобы получить хороший вывод, например,

+------------------+-----------------+
| table_name       | exact_row_count |
+------------------+-----------------+
| func             |               0 |
| general_log      |               0 |
| help_category    |              37 |
| help_keyword     |             450 |
| help_relation    |             990 |
| help_topic       |             504 |
| host             |               0 |
| ndb_binlog_index |               0 |
+------------------+-----------------+
8 rows in set (0.01 sec)
  • 2
    Спасибо, я надеялся, что мне не нужно устанавливать какие-либо плагины / гемы, чтобы получить точное количество.
  • 0
    Занимает слишком много времени для выполнения в случае большого количества таблиц в базе данных.
Показать ещё 1 комментарий
23

Я просто запускаю:

show table status;

Это даст вам количество строк для КАЖДОЙ таблицы плюс кучу другой информации. Раньше я использовал выбранный ответ выше, но это намного проще.

Я не уверен, что это работает со всеми версиями, но я использую 5.5 с движком InnoDB.

  • 4
    К сожалению, если вы используете InnoDB, этот подход страдает теми же неточностями, что и другие методы, описанные выше. Например, у меня есть таблица InnoDB, у которой есть приблизительно 65 000 строк, но эти методы здесь сообщают, что она имеет где-то от 350 000 до более 780 000.
  • 0
    Для БД с несколькими строками это довольно точно (или достаточно точно для моих нужд). Это дало мне 1086 строк для таблицы, которую COUNT (*) сообщил о 904 строках.
Показать ещё 4 комментария
8

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

Чтобы запустить его после добавления этой процедуры:

CALL `COUNT_ALL_RECORDS_BY_TABLE` ();

-

Процедура:

DELIMITER $$

CREATE DEFINER=`root`@`127.0.0.1` PROCEDURE `COUNT_ALL_RECORDS_BY_TABLE`()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE TNAME CHAR(255);

DECLARE table_names CURSOR for 
    SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE();

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN table_names;   

DROP TABLE IF EXISTS TCOUNTS;
CREATE TEMPORARY TABLE TCOUNTS 
  (
    TABLE_NAME CHAR(255),
    RECORD_COUNT INT
  ) ENGINE = MEMORY; 


WHILE done = 0 DO

  FETCH NEXT FROM table_names INTO TNAME;

   IF done = 0 THEN
    SET @SQL_TXT = CONCAT("INSERT INTO TCOUNTS(SELECT '" , TNAME  , "' AS TABLE_NAME, COUNT(*) AS RECORD_COUNT FROM ", TNAME, ")");

    PREPARE stmt_name FROM @SQL_TXT;
    EXECUTE stmt_name;
    DEALLOCATE PREPARE stmt_name;  
  END IF;

END WHILE;

CLOSE table_names;

SELECT * FROM TCOUNTS;

SELECT SUM(RECORD_COUNT) AS TOTAL_DATABASE_RECORD_CT FROM TCOUNTS;

END
6
 SELECT TABLE_NAME,SUM(TABLE_ROWS) 
 FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_SCHEMA = 'your_db' 
 GROUP BY TABLE_NAME;

Это все, что вам нужно.

  • 1
    производит приблизительные строки таблицы - сравните с "mysql_num_rows ($ tableresult)"
  • 1
    это лучший ответ на самом деле! Также проще выполнить из mysql cli: mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
2

Вы можете попробовать это. Он отлично работает для меня.

SELECT IFNULL(table_schema,'Total') "Database",TableCount 
FROM (SELECT COUNT(1) TableCount,table_schema 
      FROM information_schema.tables 
      WHERE table_schema NOT IN ('information_schema','mysql') 
      GROUP BY table_schema WITH ROLLUP) A;
2

Если вы используете базу данных information_schema, вы можете использовать этот код mysql (где часть делает запрос не отображающим таблицы, которые имеют нулевое значение для строк):

SELECT TABLE_NAME, TABLE_ROWS
FROM `TABLES`
WHERE `TABLE_ROWS` >=0
1

Там немного взлома/обходной путь к этой проблеме оценки.

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

Обнаружено это при изучении того, почему данные таблицы show не совпадают с фактическими данными.

SELECT
table_schema 'Database',
SUM(data_length + index_length) AS 'DBSize',
SUM(TABLE_ROWS) AS DBRows,
SUM(AUTO_INCREMENT) AS DBAutoIncCount
FROM information_schema.tables
GROUP BY table_schema;


+--------------------+-----------+---------+----------------+
| Database           | DBSize    | DBRows  | DBAutoIncCount |
+--------------------+-----------+---------+----------------+
| Core               |  35241984 |   76057 |           8341 |
| information_schema |    163840 |    NULL |           NULL |
| jspServ            |     49152 |      11 |            856 |
| mysql              |   7069265 |   30023 |              1 |
| net_snmp           |  47415296 |   95123 |            324 |
| performance_schema |         0 | 1395326 |           NULL |
| sys                |     16384 |       6 |           NULL |
| WebCal             |    655360 |    2809 |           NULL |
| WxObs              | 494256128 |  530533 |        3066752 |
+--------------------+-----------+---------+----------------+
9 rows in set (0.40 sec)

Затем вы могли бы легко использовать PHP или что-то еще, чтобы вернуть max из двух столбцов данных, чтобы дать "наилучшую оценку" для подсчета строк.

то есть.

SELECT
table_schema 'Database',
SUM(data_length + index_length) AS 'DBSize',
GREATEST(SUM(TABLE_ROWS), SUM(AUTO_INCREMENT)) AS DBRows
FROM information_schema.tables
GROUP BY table_schema;

Автоматическое приращение всегда будет стоять на расстоянии +1 * (столбец), но даже с 4000 таблицами и 3 миллионами строк, что на 99,9% точнее. Гораздо лучше, чем оцененные строки.

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

1

Следующий запрос создает (более строгий) запрос, который будет получать значение count (*) для каждой таблицы, из каждой схемы, указанной в информационных_схемах. Весь результат запроса, показанного здесь, - все строки, взятые вместе, - содержит действительный оператор SQL, заканчивающийся точкой с запятой - не обманывая "объединение". Объединение болтовни избегается с помощью объединения в запросе ниже.

select concat('select "', table_schema, '.', table_name, '" as `schema.table`,
                          count(*)
                 from ', table_schema, '.', table_name, ' union ') as 'Query Row'
  from information_schema.tables
 union
 select '(select null, null limit 0);';
0

Еще один вариант: для non InnoDB он использует данные из information_schema.TABLES(как это быстрее), для InnoDB - выберите count (*), чтобы получить точный счет. Также он игнорирует представления.

SET @table_schema = DATABASE();
-- or SET @table_schema = 'my_db_name';

SET GROUP_CONCAT_MAX_LEN=131072;
SET @selects = NULL;

SELECT GROUP_CONCAT(
        'SELECT "', table_name,'" as TABLE_NAME, COUNT(*) as TABLE_ROWS FROM `', table_name, '`'
        SEPARATOR '\nUNION\n') INTO @selects
  FROM information_schema.TABLES
  WHERE TABLE_SCHEMA = @table_schema
        AND ENGINE = 'InnoDB'
        AND TABLE_TYPE = "BASE TABLE";

SELECT CONCAT_WS('\nUNION\n',
  CONCAT('SELECT TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND ENGINE <> "InnoDB" AND TABLE_TYPE = "BASE TABLE"'),
  @selects) INTO @selects;

PREPARE stmt FROM @selects;
EXECUTE stmt USING @table_schema;
DEALLOCATE PREPARE stmt;

Если в вашей базе данных много больших таблиц InnoDB, считающих все строки, может потребоваться больше времени.

0

Плакат требовал подсчета строк без подсчета, но не указывал, какой движок таблицы. С InnoDB я знаю только один способ, который нужно учитывать.

Вот как я выбираю свой картофель:

# Put this function in your bash and call with:
# rowpicker DBUSER DBPASS DBNAME [TABLEPATTERN]
function rowpicker() {
    UN=$1
    PW=$2
    DB=$3
    if [ ! -z "$4" ]; then
        PAT="LIKE '$4'"
        tot=-2
    else
        PAT=""
        tot=-1
    fi
    for t in `mysql -u "$UN" -p"$PW" "$DB" -e "SHOW TABLES $PAT"`;do
        if [ $tot -lt 0 ]; then
            echo "Skipping $t";
            let "tot += 1";
        else
            c=`mysql -u "$UN" -p"$PW" "$DB" -e "SELECT count(*) FROM $t"`;
            c=`echo $c | cut -d " " -f 2`;
            echo "$t: $c";
            let "tot += c";
        fi;
    done;
    echo "total rows: $tot"
}

Я не делаю никаких утверждений об этом, кроме того, что это действительно уродливый, но эффективный способ получить, сколько строк существует в каждой таблице в базе данных, независимо от механизма таблицы и без необходимости иметь разрешение на установку хранимых процедур и без необходимо установить ruby ​​или php. Да, его ржавый. Да, это важно. count (*) является точным.

0

Это то, что я делаю, чтобы получить фактический счет (без использования схемы)

Это медленнее, но точнее.

Это двухэтапный процесс в

  • Получить список таблиц для вашего db. Вы можете получить его с помощью

    mysql -uroot -p mydb -e "show tables"
    
  • Создайте и назначьте список таблиц переменной массива в этом bash script (разделенном одним пробелом, как в приведенном ниже коде)

    array=( table1 table2 table3 )
    
    for i in "${array[@]}"
    do
        echo $i
        mysql -uroot mydb -e "select count(*) from $i"
    done
    
  • Запустите его:

    chmod +x script.sh; ./script.sh
    
0

Вот как я подсчитываю ТАБЛИЦЫ и ВСЕ ЗАПИСИ с помощью PHP:

$dtb = mysql_query("SHOW TABLES") or die (mysql_error());
$jmltbl = 0;
$jml_record = 0;
$jml_record = 0;

while ($row = mysql_fetch_array($dtb)) { 
    $sql1 = mysql_query("SELECT * FROM " . $row[0]);            
    $jml_record = mysql_num_rows($sql1);            
    echo "Table: " . $row[0] . ": " . $jml_record record . "<br>";      
    $jmltbl++;
    $jml_record += $jml_record;
}

echo "--------------------------------<br>$jmltbl Tables, $jml_record > records.";
0

Если вам нужны точные цифры, используйте следующий ruby ​​ script. Вам нужны Ruby и RubyGems.

Установить следующие драгоценные камни:

$> gem install dbi
$> gem install dbd-mysql

Файл: count_table_records.rb

require 'rubygems'
require 'dbi'

db_handler = DBI.connect('DBI:Mysql:database_name:localhost', 'username', 'password')

# Collect all Tables
sql_1 = db_handler.prepare('SHOW tables;')
sql_1.execute
tables = sql_1.map { |row| row[0]}
sql_1.finish

tables.each do |table_name|
  sql_2 = db_handler.prepare("SELECT count(*) FROM #{table_name};")
  sql_2.execute
  sql_2.each do |row|
    puts "Table #{table_name} has #{row[0]} rows."
  end
  sql_2.finish
end

db_handler.disconnect

Вернитесь к командной строке:

$> ruby count_table_records.rb

Вывод:

Table users has 7328974 rows.
-1

Если вы знаете количество таблиц и их имена и предполагаете, что у каждого из них есть первичные ключи, вы можете использовать кросс-соединение в комбинации с COUNT(distinct [column]), чтобы получить строки, которые поступают из каждой таблицы:

SELECT 
   COUNT(distinct t1.id) + 
   COUNT(distinct t2.id) + 
   COUNT(distinct t3.id) AS totalRows
FROM firstTable t1, secondTable t2, thirdTable t3;

Вот пример SQL Fiddle.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню