MySQLデータベースのすべてのテーブルのレコード数を取得する


347

SELECT count()各テーブルでを実行せずに、MySQLデータベースのすべてのテーブルの行数を取得する方法はありますか?


1
:InnoDBのためにも正確である拡張答えstackoverflow.com/questions/24707814/...
gwideman

1
SELECT count(table_name)FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'YOUR_DB'は、データベース内のテーブルの数を示します
shasi kanth

回答:


416
SELECT SUM(TABLE_ROWS) 
     FROM INFORMATION_SCHEMA.TABLES 
     WHERE TABLE_SCHEMA = '{your_db}';

ただし、ドキュメントからの注記: InnoDBテーブルの場合、行数は SQL最適化で使用れる大まかな見積もりにすぎません。正確なカウントを行うには、COUNT(*)を使用する必要があります(コストが高くなります)。


266
または、各テーブルに必要な場合:SELECT table_name、TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}';
TheSoftwareJedi 2008年

5
table_rowとtable_nameを取得する他の方法はありますか?大まかな見積もりではなく正確な結果が欲しいので。ありがとうございました。
クルナルシャー

3
@krunalshah、これはInnoDBの制限の1つです。詳細については、dev.mysql.com / doc / refman / 5.0 / en / innodb-restrictions.htmlのセクション「InnoDBテーブルの制限」を参照してください。常にSELECT COUNT(*)FROM tを使用できますが、これはかなり遅くなります
マーク

2
ハイツ、そうじゃない。count(*)(またはより現実的にはcount(id))は、mysqlが行をカウントするために使用するものではありませんか?いずれにせよ、私はそれをテストしただけで、count()コールの数値が大きくなりました。
codygman 2013年

2
SELECT TABLE_NAME、SUM(TABLE_ROWS)N FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}' group by TABLE_NAME;
PiyusG 2014年

175

あなたはおそらくTables tableと一緒に何かを置くことができます。一度も行ったことはありませんが、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が言及したように、これは推定値を返すだけで、数回実行すると異なる結果を返す可能性があります
Kris

少なくとも250レコードのテーブルは、このクエリを実行するたびに異なる行数を報告するようです。
Arthur

おっと...「Estimated」という言葉を目の前で見ていたらいいのに...昨日のように!答えは拒否されるべきではありませんか?OPが「推定」を要求しなかったので、彼が推定を望んでいるかもしれないと考えるのはばかげているようです。「見積もり」私のような栗色の人が「見積もり」を見逃すのを防ぐことができましたか?
Kreeverp

111

@Venkatramananなどのように、INNODB、MySQL 5.1.44を使用して、INFORMATION_SCHEMA.TABLESが信頼できないと判断し、静止したテーブルでさえ実行するたびに異なる行数を与えました。Rubyの宝石などをインストールせずに新しいクエリに貼り付けることができる大きなSQLステートメントを生成する比較的ハックな(しかし柔軟で適応可能な)方法を次に示します。

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
おかげで、正確な数を取得するためにプラグインや宝石をインストールする必要がないことを望んでいました。
bradvido 2014

データベースに多数のテーブルがある場合、実行に時間がかかりすぎます。
ollamh

1
最後のUNIONを削除した後、生成されたクエリの最後に、「select * from( "で始まり、")として出力順序として「exact_row_count descで」を追加して、テーブルカウントdescで順序を取得
Raghavendra

ビューを除外するには:WHERE table_schema = ' my_schema 'およびTABLE_TYPE LIKE '%TABLE%'
Watson

38

私は走るだけです:

show table status;

これにより、すべてのテーブルの行数に加えて、その他の情報が表示されます。私は上記の選択された答えを使用していましたが、これははるかに簡単です。

これがすべてのバージョンで機能するかどうかはわかりませんが、InnoDBエンジンで5.5を使用しています。


5
残念ながら、InnoDBを使用している場合、このアプローチは上記の他の方法と同じ不正確さに悩まされます。たとえば、約65,000行のInnoDBテーブルがありますが、ここでのこれらのメソッドは、350,000から780,000を超える場所があると報告しています。
PeterToTheThird 14年

行が少ないDBの場合、それはかなり正確です(または、私のニーズに対して十分正確です)。COUNT(*)が904行を報告したテーブルの1086行を取得しました。
Magne、2014

最善の答えです。私はInnoDBを使用していますが、大きさの順序を知るための簡単なコマンドだけが必要です。
Nemo

真剣に、これが受け入れられたことを願っています。InnoDBを使用していないため、正確な回答が得られます。
Kolob Canyon 2016

1
行番号は正確ではありませんが、そのようなテーブルから行を削除しなかった場合、「Auto_increment」は正確な番号を提供します。
Peter T.

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

それで十分です。


1
推定テーブル行を生成します-「mysql_num_rows($ tableresult)」と比較します
Kreeverp

1
それが実際に最良の答えです!mysqlのCLIから実行することも単純:mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
loretoparisi

11

このストアドプロシージャは、テーブルを一覧表示し、レコードをカウントして、最後に合計レコード数を生成します。

この手順を追加した後に実行するには:

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

8

簡単な方法:

SELECT
  TABLE_NAME, SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{Your_DB}'
GROUP BY TABLE_NAME;

結果の例:

+----------------+-----------------+
| TABLE_NAME     | SUM(TABLE_ROWS) |
+----------------+-----------------+
| calls          |            7533 |
| courses        |             179 |
| course_modules |             298 |
| departments    |              58 |
| faculties      |             236 |
| modules        |             169 |
| searches       |           25423 |
| sections       |             532 |
| universities   |              57 |
| users          |           10293 |
+----------------+-----------------+

4

この見積もりの​​問題には少しハック/回避策があります。

Auto_Increment-何らかの理由で、テーブルに自動インクリメントが設定されている場合、これはデータベースのはるかに正確な行数を返します。

これは、show table infoが実際のデータと一致しない理由を調べたときに見つかりました。

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などを簡単に使用して、2つのデータ列の最大値を返し、行数の「最良の見積もり」を与えることができます。

すなわち

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 *(テーブルカウント)行オフになりますが、4,000テーブルと300万行の場合でも、99.9%正確です。推定された行よりもはるかに優れています。

これのすばらしい点は、performance_schemaで返される行カウントも消去されることです。これは、最大値がnullに作用しないためです。ただし、自動インクリメントのテーブルがない場合は、これが問題になる可能性があります。


3

これを試すことができます。それは私にとってはうまくいきます。

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コードを使用できます(where部分により、クエリは行にnull値を持つテーブルを表示しません)。

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

1

次のクエリは、(別の)クエリを生成し、information_schema.tablesにリストされているすべてのスキーマから、すべてのテーブルの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);';

1

これは私が実際のカウントを取得するために行うことです(スキーマを使用しません)

速度は遅くなりますが、より正確です。

それは2段階のプロセスです

  1. データベースのテーブルのリストを取得します。あなたはそれを使ってそれを得ることができます

    mysql -uroot -p mydb -e "show tables"
  2. このbashスクリプトで、テーブルのリストを作成して配列変数に割り当てます(以下のコードのように、1つのスペースで区切ります)。

    array=( table1 table2 table3 )
    
    for i in "${array[@]}"
    do
        echo $i
        mysql -uroot mydb -e "select count(*) from $i"
    done
  3. それを実行します:

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

1

もう1つのオプション: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

これは、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.";

データを無視する場合は、なぜcount(*)を使用しないのですか?
Svetoslav Marinov

0

ポスターはカウントせずに行数を求めましたが、どのテーブルエンジンを指定していませんでした。InnoDBを使用する場合、数えるという方法は1つしかわかりません。

これは私が私のジャガイモを選ぶ方法です:

# 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"
}

これは、テーブルエンジンに関係なく、ストアドプロシージャをインストールする権限がなくても、またインストールする必要もなく、データベース内の各テーブルに存在する行数を取得するための本当に醜いが効果的な方法であるということを除いて、これについては何も言明していません。ルビーまたはphp。はい、錆びています。はい、それは数えます。count(*)は正確です。


0

上記の@Nathanの回答に基づいていますが、「最後のユニオンを削除する」必要がなく、出力をソートするオプションがあるため、次のSQLを使用しています。次のSQLステートメントが生成され、実行されます。

select CONCAT( 'select * from (\n', group_concat( single_select SEPARATOR ' UNION\n'), '\n ) Q order by Q.exact_row_count desc') as sql_query
from (
    SELECT CONCAT(
        'SELECT "', 
        table_name, 
        '" AS table_name, COUNT(1) AS exact_row_count
        FROM `', 
        table_schema,
        '`.`',
        table_name, 
        '`'
    ) as single_select
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE table_schema = 'YOUR_SCHEMA_NAME'
      and table_type = 'BASE TABLE'
) Q 

group_concat_max_lenサーバー変数には十分に大きな値が必要ですが、MariaDb 10.2.4以降では、デフォルトで1Mになっているはずです。


0

以下のコードは、すべての物語の選択クエリを生成します。最後の「UNION ALL」を削除してすべての結果を選択し、新しいクエリウィンドウを貼り付けて実行します。

SELECT 
concat('select ''', table_name ,''' as TableName, COUNT(*) as RowCount from ' , table_name , ' UNION ALL ')  as TR FROM
information_schema.tables where 
table_schema = 'Database Name'

-1

正確な数値が必要な場合は、次のルビスクリプトを使用します。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.

-4

テーブルの数とその名前がわかっていて、それぞれに主キーがあると想定している場合、クロス結合を組み合わせて使用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の例です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.