Dapatkan jumlah catatan untuk semua tabel di database MySQL

347

Apakah ada cara untuk mendapatkan jumlah baris di semua tabel dalam database MySQL tanpa menjalankan SELECT count()setiap tabel?

Menandai
sumber
1
Jawaban yang diperluas itu juga akurat untuk InnoDB: stackoverflow.com/questions/24707814/…
gwideman
1
Hitungan SELECT (table_name) DARI INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'YOUR_DB' akan memberikan jumlah tabel dalam database Anda
shasi kanth

Jawaban:

416
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).

Benci_
sumber
266
atau, jika Anda ingin untuk setiap tabel: SELECT table_name, TABLE_ROWS DARI INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}';
TheSoftwareJedi
5
Apakah ada cara lain untuk mendapatkan table_row dan table_name? Karena saya ingin hasil pasti bukan perkiraan kasar. Terima kasih.
krunal shah
3
@krunalshah, Ini adalah salah satu batasan InnoDB. Lihat dev.mysql.com/doc/refman/5.0/id/innodb-restrictions.html , bagian Pembatasan pada Tabel InnoDB, untuk info lebih lanjut. Anda selalu dapat menggunakan COUNT SELECT (*) DARI t, yang bagaimanapun, jauh lebih lambat
Menandai
2
Jaitsu, tidak. count (*) (atau lebih realistis count (id)) adalah apa yang mysql gunakan untuk menghitung baris itu bukan? Bagaimanapun, saya hanya mengujinya dan mendapat nomor yang lebih besar untuk panggilan count (), berapa pun nilainya.
codygman
2
SELECT TABLE_NAME, SUM (TABLE_ROWS) N DARI INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = grup '{your_db}' oleh TABLE_NAME;
PiyusG
175

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**';
gpojd
sumber
4
Apakah ada cara lain untuk mendapatkan table_row dan table_name? Karena saya ingin hasil pasti bukan perkiraan kasar. Terima kasih.
krunal shah
1
seperti kuranl menyebutkan ini mengembalikan hanya perkiraan dan mungkin akan mengembalikan hasil yang berbeda ketika dijalankan beberapa kali
Kris
Tabel dengan setidaknya ~ 250 catatan tampaknya melaporkan jumlah baris yang berbeda setiap kali saya menjalankan kueri ini.
Arthur
Ups ... berharap aku akan melihat kata "Diperkirakan" sebelumnya ... seperti kemarin! Bukankah seharusnya jawaban ditolak? Karena OP tidak meminta "perkiraan" dan tampaknya konyol untuk berpikir bahwa ia mungkin menginginkan perkiraan. "Perkiraan" Bisakah menyelamatkan maroon seperti saya dari melewatkan "perkiraan"?
Kreeverp
111

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)
Nathan
sumber
2
Terima kasih, saya berharap saya tidak perlu menginstal plugin / permata untuk mendapatkan jumlah yang tepat.
bradvido
Butuh waktu terlalu lama untuk mengeksekusi jika ada banyak tabel dalam database.
ollamh
1
tambahkan "pilih * dari (" di awal dan ") sebagai urutan keluaran dengan exact_row_count desc" di akhir kueri yang dihasilkan setelah menghapus UNION terakhir untuk mendapatkan pesanan menurut jumlah meja desc
Raghavendra
Untuk mengecualikan tampilan: WHERE table_schema = ' my_schema ' dan TABLE_TYPE SUKA '% TABLE%'
Watson
38

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.

djburdick
sumber
5
Sayangnya, jika Anda menggunakan InnoDB, pendekatan ini mengalami ketidakakuratan yang sama seperti metode lain yang dijelaskan di atas. Sebagai contoh, saya memiliki tabel InnoDB yang memiliki sekitar 65.000 baris, namun metode ini di sini melaporkan bahwa ia memiliki antara 350.000 hingga lebih dari 780.000.
PeterToTheThird
Untuk DB dengan beberapa baris, ini cukup akurat (atau, cukup akurat untuk kebutuhan saya). Ini memberi saya 1086 baris untuk tabel yang COUNT (*) melaporkan 904 baris.
Magne
Sejauh ini jawaban terbaik. Saya menggunakan InnoDB tetapi saya hanya perlu perintah cepat untuk mengetahui urutan besarnya.
Nemo
Serius, berharap ini diterima. Tidak menggunakan InnoDB dan memberi saya jawaban yang tepat.
Ngarai Kolob
1
Nomor baris tidak akurat tetapi "Auto_increment" dapat memberi Anda nomor akurat jika Anda tidak menghapus baris apa pun dari tabel tersebut.
Peter T.
13
 SELECT TABLE_NAME,SUM(TABLE_ROWS) 
 FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_SCHEMA = 'your_db' 
 GROUP BY TABLE_NAME;

Itu yang kamu butuhkan.

Gustavo Castro
sumber
1
menghasilkan taksiran baris tabel - bandingkan dengan "mysql_num_rows ($ tableresult)"
Kreeverp
1
itu jawaban terbaik sebenarnya! Juga lebih mudah untuk dieksekusi dari mysql cli:mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
loretoparisi
11

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
Jake Drew
sumber
8

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 |
+----------------+-----------------+
Eduardo Cuomo
sumber
4

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.

pengguna3260912
sumber
3

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;
Nimesh07
sumber
2

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
Robin Manoli
sumber
1

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);';
pengguna1575139
sumber
1

Inilah yang saya lakukan untuk mendapatkan jumlah sebenarnya (tidak menggunakan skema)

Lebih lambat tapi lebih akurat.

Ini adalah proses dua langkah di

  1. Dapatkan daftar tabel untuk db Anda. Anda bisa menggunakannya

    mysql -uroot -p mydb -e "show tables"
  2. 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
  3. Menjalankannya:

    chmod +x script.sh; ./script.sh
laffie
sumber
1

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.

filimonov
sumber
0

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.";
koswara1482
sumber
Mengapa Anda tidak menggunakan hitungan (*) jika Anda akan mengabaikan data?
Svetoslav Marinov
0

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.

apotek
sumber
0

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_lenvariabel server tetapi dari MariaDb 10.2.4 itu harus default ke 1M.

Adam
sumber
0

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'
luas
sumber
-1

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.
Michael Voigt
sumber
-4

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 .

AdamMc331
sumber