各テーブルでを実行せずに、MySQLデータベース内のすべてのテーブルの行数を取得する方法はありSELECT count()
ますか?
19 に答える
SELECT SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{your_db}';
ただし、ドキュメントからの注意: InnoDBテーブルの場合、行数はSQL最適化で使用される概算にすぎません。正確なカウントにはCOUNT(*)を使用する必要があります(これはより高価です)。
あなたはおそらくテーブルテーブルと何かを組み合わせることができます。一度も行ったことがありませんが、TABLE_ROWS用の列とTABLENAME用の列があるようです。
テーブルごとの行を取得するには、次のようなクエリを使用できます。
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '**YOUR SCHEMA**';
@Venkatramanan などと同様に、INFORMATION_SCHEMA.TABLES は信頼性が低く (InnoDB、MySQL 5.1.44 を使用)、静止テーブルでも実行するたびに異なる行数を示します。これは、Ruby gem などをインストールせずに、新しいクエリに貼り付けることができる大きな 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)
私はただ実行します:
show table status;
これにより、すべてのテーブルの行数とその他の情報が得られます。上記の選択した回答を使用していましたが、これははるかに簡単です。
これがすべてのバージョンで機能するかどうかはわかりませんが、InnoDB エンジンで 5.5 を使用しています。
SELECT TABLE_NAME,SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_db'
GROUP BY TABLE_NAME;
それだけです。
このストアド プロシージャは、テーブルを一覧表示し、レコードをカウントして、最後にレコードの総数を生成します。
このプロシージャを追加した後に実行するには:
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
この見積もりの問題には、ちょっとしたハック/回避策があります。
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% の精度です。推定行数よりもはるかに優れています。
これの利点は、null に対して maximum が機能しないため、performance_schema で返される行数も消去されることです。ただし、自動インクリメントを備えたテーブルがない場合、これは問題になる可能性があります。
これを試すことができます。それは私にとってはうまくいっています。
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;
データベース information_schema を使用する場合は、次の mysql コードを使用できます (where 部分により、行に null 値を持つテーブルがクエリに表示されなくなります)。
SELECT TABLE_NAME, TABLE_ROWS
FROM `TABLES`
WHERE `TABLE_ROWS` >=0
これは、実際のカウントを取得するために行うことです (スキーマを使用しません)。
遅いですが、より正確です。
これは 2 段階のプロセスです。
データベースのテーブルのリストを取得します。を使用して取得できます
mysql -uroot -p mydb -e "show tables"
テーブルのリストを作成して、この bash スクリプトの配列変数に割り当てます (以下のコードのように、1 つのスペースで区切ります)。
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
次のクエリは、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);';
これは、PHP を使用して TABLES と ALL RECORDS をカウントする方法です。
$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.";
正確な数値が必要な場合は、次の Ruby スクリプトを使用します。Ruby と RubyGems が必要です。
次の Gem をインストールします。
$> 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.
以下のコードは、すべてのテイルの選択クエリを生成します。最後の「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'