Apakah ada cara untuk mendapatkan jumlah baris di semua tabel dalam database MySQL tanpa menjalankan SELECT count()
setiap tabel?
Apakah ada cara untuk mendapatkan jumlah baris di semua tabel dalam database MySQL tanpa menjalankan SELECT count()
setiap tabel?
Jawaban:
SELECT SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{your_db}';
Catatan dari dokumen: Untuk tabel InnoDB, jumlah baris hanya perkiraan kasar yang digunakan dalam optimasi SQL. Anda harus menggunakan COUNT (*) untuk penghitungan yang tepat (yang lebih mahal).
Anda mungkin bisa meletakkan sesuatu bersama dengan tabel Tables . Saya belum pernah melakukannya, tetapi sepertinya memiliki kolom untuk TABLE_ROWS dan satu untuk TABLE NAME .
Untuk mendapatkan baris per tabel, Anda dapat menggunakan kueri seperti ini:
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '**YOUR SCHEMA**';
Seperti @Venkatramanan dan yang lainnya, saya menemukan INFORMATION_SCHEMA.TABLES tidak dapat diandalkan (menggunakan InnoDB, MySQL 5.1.44), memberikan jumlah baris yang berbeda setiap kali saya menjalankannya bahkan pada tabel quiesced. Berikut ini cara yang relatif retas (tapi fleksibel / mudah beradaptasi) untuk menghasilkan pernyataan SQL besar yang dapat Anda tempelkan ke dalam kueri baru, tanpa memasang permata dan barang-barang 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**';
Ini menghasilkan output seperti ini:
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
Salin dan tempel kecuali untuk UNION terakhir untuk mendapatkan hasil yang bagus seperti,
+------------------+-----------------+
| 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)
Saya hanya menjalankan:
show table status;
Ini akan memberi Anda jumlah baris untuk SETIAP tabel plus banyak info lainnya. Saya dulu menggunakan jawaban yang dipilih di atas, tetapi ini jauh lebih mudah.
Saya tidak yakin apakah ini bekerja dengan semua versi, tapi saya menggunakan 5,5 dengan mesin InnoDB.
SELECT TABLE_NAME,SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_db'
GROUP BY TABLE_NAME;
Itu yang kamu butuhkan.
mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
Prosedur tersimpan ini mencantumkan tabel, menghitung catatan, dan menghasilkan jumlah total catatan pada akhirnya.
Untuk menjalankannya setelah menambahkan prosedur ini:
CALL `COUNT_ALL_RECORDS_BY_TABLE` ();
-
Prosedur:
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
Cara sederhana:
SELECT
TABLE_NAME, SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{Your_DB}'
GROUP BY TABLE_NAME;
Contoh hasil:
+----------------+-----------------+
| 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 |
+----------------+-----------------+
Ada sedikit peretasan / solusi untuk masalah perkiraan ini.
Auto_Increment - karena alasan tertentu ini mengembalikan jumlah baris yang jauh lebih akurat untuk database Anda jika Anda memiliki kenaikan otomatis yang diatur pada tabel.
Menemukan ini ketika menjelajahi mengapa info tabel tunjukkan tidak cocok dengan data aktual.
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)
Anda kemudian dapat dengan mudah menggunakan PHP atau apa pun untuk mengembalikan maks 2 kolom data untuk memberikan "perkiraan terbaik" untuk jumlah baris.
yaitu
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;
Peningkatan Otomatis akan selalu menjadi baris +1 * (hitungan tabel), tetapi bahkan dengan 4.000 tabel dan 3 juta baris, itu 99,9% akurat. Jauh lebih baik dari perkiraan baris.
Keindahan dari ini adalah bahwa jumlah baris yang dikembalikan dalam performance_schema dihapus untuk Anda, juga, karena terhebat tidak bekerja pada nol. Ini mungkin menjadi masalah jika Anda tidak memiliki tabel dengan kenaikan otomatis.
Anda bisa mencoba ini. Ini bekerja dengan baik untuk saya.
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;
Jika Anda menggunakan database information_schema, Anda dapat menggunakan kode mysql ini (bagian mana membuat kueri tidak menampilkan tabel yang memiliki nilai nol untuk baris):
SELECT TABLE_NAME, TABLE_ROWS
FROM `TABLES`
WHERE `TABLE_ROWS` >=0
Kueri berikut menghasilkan kueri (nother) yang akan mendapatkan nilai count (*) untuk setiap tabel, dari setiap skema, yang tercantum di information_schema.tables. Seluruh hasil kueri yang ditampilkan di sini - semua baris yang diambil bersamaan - terdiri dari pernyataan SQL yang valid yang diakhiri dengan tanda titik koma - tidak ada 'persatuan' yang menggantung. Serikat penggantung dihindari dengan menggunakan serikat dalam kueri di bawah ini.
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);';
Inilah yang saya lakukan untuk mendapatkan jumlah sebenarnya (tidak menggunakan skema)
Lebih lambat tapi lebih akurat.
Ini adalah proses dua langkah di
Dapatkan daftar tabel untuk db Anda. Anda bisa menggunakannya
mysql -uroot -p mydb -e "show tables"
Buat dan tetapkan daftar tabel ke variabel array di skrip bash ini (dipisahkan oleh satu spasi seperti pada kode di bawah ini)
array=( table1 table2 table3 )
for i in "${array[@]}"
do
echo $i
mysql -uroot mydb -e "select count(*) from $i"
done
Menjalankannya:
chmod +x script.sh; ./script.sh
Satu lagi opsi: untuk non InnoDB menggunakan data dari information_schema.TABLES (karena lebih cepat), untuk InnoDB - pilih hitungan (*) untuk mendapatkan penghitungan yang akurat. Itu juga mengabaikan pandangan.
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;
Jika database Anda memiliki banyak tabel InnoDB besar, menghitung semua baris dapat memakan waktu lebih banyak.
Ini adalah bagaimana saya menghitung TABEL dan SEMUA RECORDS menggunakan 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.";
Poster menginginkan jumlah baris tanpa menghitung, tetapi tidak menentukan mesin tabel mana. Dengan InnoDB, saya hanya tahu satu cara, yaitu menghitung.
Inilah cara saya memilih kentang:
# 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"
}
Saya tidak membuat pernyataan tentang ini selain bahwa ini adalah cara yang benar-benar jelek tapi efektif untuk mendapatkan berapa banyak baris yang ada di setiap tabel dalam database terlepas dari mesin tabel dan tanpa harus memiliki izin untuk menginstal prosedur tersimpan, dan tanpa perlu menginstal ruby atau php. Ya, berkarat. Ya itu penting. hitungan (*) akurat.
Berdasarkan jawaban @ Nathan di atas, tetapi tanpa perlu "menghapus serikat final" dan dengan opsi untuk mengurutkan output, saya menggunakan SQL berikut. Ini menghasilkan pernyataan SQL lain yang kemudian jalankan:
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
Anda memang membutuhkan nilai yang cukup besar dari group_concat_max_len
variabel server tetapi dari MariaDb 10.2.4 itu harus default ke 1M.
Kode di bawah ini menghasilkan kueri pemilihan untuk semua kisah. Hapus saja "UNION ALL" lalu pilih semua hasil dan rekatkan jendela kueri baru untuk dijalankan.
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'
Jika Anda ingin angka pastinya, gunakan skrip ruby berikut. Anda membutuhkan Ruby dan RubyGems.
Instal Permata berikut:
$> gem install dbi
$> gem install dbd-mysql
File: 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
Kembali ke baris perintah:
$> ruby count_table_records.rb
Keluaran:
Table users has 7328974 rows.
Jika Anda tahu jumlah tabel dan namanya, dan dengan asumsi masing-masing memiliki kunci utama, Anda bisa menggunakan gabungan silang dengan COUNT(distinct [column])
untuk mendapatkan baris yang berasal dari setiap tabel:
SELECT
COUNT(distinct t1.id) +
COUNT(distinct t2.id) +
COUNT(distinct t3.id) AS totalRows
FROM firstTable t1, secondTable t2, thirdTable t3;
Berikut ini adalah contoh SQL Fiddle .