MySQL veritabanındaki tüm tablolar için kayıt sayısı alma


347

SELECT count()Her tabloda bir çalıştırma yapmadan MySQL veritabanındaki tüm tablolardaki satır sayısını almanın bir yolu var mı ?


1
InnoDB için de doğru olan genişletilmiş yanıt: stackoverflow.com/questions/24707814/…
gwideman

1
SELECT sayımı (tablo_adı) FABLE information_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'YOUR_DB' veri tabanınızdaki tablo sayısını verecektir
shasi kanth

Yanıtlar:


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

Yine de dokümanlardan not: InnoDB tabloları için satır sayısı SQL optimizasyonunda kullanılan kabaca bir tahmindir . Tam sayımlar için COUNT (*) kullanmanız gerekir (bu daha pahalıdır).


267
veya her tablo için isterseniz: SELECT table_name, TABLE_ROWS FROM information_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}';
TheSoftwareJedi

5
Table_row ve table_name almanın başka bir yolu var mı? Çünkü kesin sonuç değil kaba tahmin istiyorum. Teşekkür ederim.
krunal shah

3
@krunalshah, Bu InnoDB kısıtlamalarından biridir. Daha fazla bilgi için dev.mysql.com/doc/refman/5.0/tr/innodb-restrictions.html , InnoDB Tablolarındaki Kısıtlamalar bölümüne bakın . Her zaman ancak çok yavaş t GELEN bir SELECT COUNT (*), kullanabilirsiniz
İşaretleme

2
Jaitsu, hayır değil. count (*) (veya daha gerçekçi olarak count (id)) mysql'in satırları saymak için kullandığı şey bu değil mi? Her durumda, sadece test ettim ve ne olursa olsun count () çağrısı için daha büyük bir sayı aldım.
codygman

2
TABLE_NAME, TABLE_SCHEMA = '{your_db}' grubundan BİLGİ_SCHEMA.TABLES'DEN TOPLA (TABLE_ROWS) N SEÇİN;
PiyusG

177

Muhtemelen Tablolar tablosu ile bir şeyler koyabilirsiniz . Bunu hiç yapmadım, ancak TABLE_ROWS için bir sütun ve TABLE NAME için bir sütun var gibi görünüyor .

Tablo başına satır almak için aşağıdaki gibi bir sorgu kullanabilirsiniz:

SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '**YOUR SCHEMA**';

4
Table_row ve table_name almanın başka bir yolu var mı? Çünkü kesin sonuç değil kaba tahmin istiyorum. Teşekkür ederim.
krunal shah

1
kuranl'ın belirttiği gibi, bu sadece bir tahmin döndürür ve birkaç kez çalıştırıldığında muhtemelen farklı sonuçlar döndürür
Kris

En az ~ 250 kayıt içeren tablolar bu sorguyu her çalıştırdığımda farklı sayıda satır rapor gibi görünüyor.
Arthur

Ooops ... keşke daha önce "Tahmini" kelimesini görseydim ... dün gibi! Cevap reddedilmemeli mi? OP "tahmini" istemediğinden ve bir tahmin isteyebileceğini düşünmek aptalca gözüküyor. "tahmin" Benim gibi bordoları "tahmini" kaçırmaktan kurtarabilir misiniz?
Kreeverp

111

@Venkatramanan ve diğerleri gibi, bilgi tablolarında bile her çalıştırdığımda farklı satır sayıları vererek BİLGİ_SCHEMA.TABLES'i güvenilmez buldum (InnoDB, MySQL 5.1.44 kullanarak). İşte Ruby taşlar ve şeyler yüklemeden yeni bir sorguya yapıştırabileceğiniz büyük bir SQL ifadesi oluşturmanın nispeten sert (ancak esnek / uyarlanabilir) bir yolu.

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**';

Bunun gibi çıktılar üretir:

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 

Gibi güzel çıktılar almak için son UNION dışında kopyalayıp yapıştırın,

+------------------+-----------------+
| 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
Teşekkürler, kesin sayımlar elde etmek için herhangi bir eklenti / mücevher yüklemem gerekmediğini umuyordum.
bradvido

Veritabanında çok sayıda tablo olması durumunda yürütülmesi çok uzun sürer.
ollamh

1
tablo sayısına göre sipariş almak için son UNION kaldırıldıktan sonra oluşturulan sorgunun sonuna "başlangıç ​​* ve") tam_row_count desc tarafından çıkış sırası olarak ekleyin "
Raghavendra

Görünümleri hariç tutmak için: WHERE table_schema = ' my_schema ' ve TABLE_TYPE GİBİ '% TABLE%'
Watson

39

Sadece koşuyorum:

show table status;

Bu size HER tablo için satır sayısı artı bir dizi başka bilgi verecektir. Yukarıda seçilen cevabı kullanırdım, ama bu çok daha kolay.

Bunun tüm sürümlerle çalışıp çalışmadığından emin değilim, ancak InnoDB motoruyla 5.5 kullanıyorum.


5
Ne yazık ki, InnoDB kullanıyorsanız, bu yaklaşım yukarıda açıklanan diğer yöntemlerle aynı yanlışlıklardan muzdariptir. Örneğin, yaklaşık 65.000 satır içeren bir InnoDB tablom var, ancak bu yöntemlerin burada 350.000 ila 780.000'den fazla olduğu bildiriliyor.
PeterToTheThird

Birkaç sıralı bir DB için oldukça doğrudur (veya ihtiyaçlarım için yeterince doğrudur). COUNT (*) öğesinin 904 satır bildirdiği bir tablo için bana 1086 satır verdi.
Magne

En iyi cevap. InnoDB kullanıyorum ama büyüklük sırasını bilmek için sadece hızlı bir komuta ihtiyacım var.
Nemo

Cidden, bunun kabul edilmesini dilerdim. InnoDB kullanmıyorum ve bana kesin cevap veriyor.
Kolob Kanyonu

1
Satır sayısı doğru değil, ancak bu tür tablolardan herhangi bir satır silmediyseniz "Auto_increment" size doğru sayı verebilir.
Peter T.

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

Tek ihtiyacınız olan bu.


1
tahmini tablo satırları üretir - "mysql_num_rows ($ tableresult)" ile karşılaştır
Kreeverp

1
aslında en iyi cevap bu! Ayrıca mysql cli yürütülecek daha basit:mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
loretoparisi

11

Bu saklı yordam tabloları listeler, kayıtları sayar ve sonunda toplam kayıt sayısı üretir.

Bu yordamı ekledikten sonra çalıştırmak için:

CALL `COUNT_ALL_RECORDS_BY_TABLE` ();

-

Prosedür:

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

Basit yol:

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

Sonuç örneği:

+----------------+-----------------+
| 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

Bu tahminde bulunma sorununun bir kesilmesi / çözümü vardır.

Auto_Increment - herhangi bir nedenle, tablolarda otomatik artış ayarladıysanız, veritabanınız için çok daha doğru bir satır sayısı döndürür.

Şov tablosu bilgisinin neden gerçek verilerle eşleşmediğini keşfederken bunu buldum.

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)

Daha sonra kolayca PHP veya satır sayısı için "en iyi tahmin" vermek için 2 veri sütunlarının maksimum döndürmek için ne olursa olsun kullanabilirsiniz.

yani

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;

Otomatik Artış her zaman +1 * (tablo sayısı) satırlar kapalı olacaktır, ancak 4.000 tablo ve 3 milyon satırla bile, bu% 99,9 doğrudur. Tahmin edilen satırlardan çok daha iyi.

Bunun güzelliği, performance_schema'da döndürülen satır sayımlarının sizin için de silinmesidir, çünkü en büyüğü boşta çalışmaz. Otomatik artışlı tablolarınız yoksa bu bir sorun olabilir.


3

Bunu deneyebilirsiniz. Benim için iyi çalışıyor.

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

İnfo_schema veritabanı kullanıyorsanız, bu mysql kodunu kullanabilirsiniz (burada bölüm sorguyu satırlar için boş değeri olan tabloları göstermez):

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

1

Aşağıdaki sorgu, information_schema.tables içinde listelenen her şemadan, her tablo için count (*) değerini alacak bir (nother) sorgu üretir. Burada gösterilen sorgunun tüm sonucu - birlikte alınan tüm satırlar - noktalı virgülle biten geçerli bir SQL ifadesi içerir - sarkan 'birleşim' yoktur. Sarkan sendika, aşağıdaki sorguda bir sendika kullanılarak önlenir.

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

Bu gerçek sayımı almak için yaptığım şeydir (şemayı kullanmadan)

Daha yavaş ama daha doğru.

Bu iki adımlı bir süreçtir.

  1. Db için tabloların listesini alın. Kullanarak alabilirsiniz

    mysql -uroot -p mydb -e "show tables"
  2. Bu bash betiğindeki dizi değişkenine tablo listesini oluşturun ve atayın (aşağıdaki kodda olduğu gibi tek bir boşlukla ayrılmış)

    array=( table1 table2 table3 )
    
    for i in "${array[@]}"
    do
        echo $i
        mysql -uroot mydb -e "select count(*) from $i"
    done
  3. Çalıştır:

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

1

Bir seçenek daha: InnoDB olmayanlar için, information_schema.TABLES (daha hızlı olduğu gibi) verilerini kullanır, InnoDB için - doğru sayımı elde etmek için sayımı (*) seçin. Ayrıca görünümleri yok sayar.

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;

Veritabanınızda çok sayıda büyük InnoDB tablosu varsa, tüm satırları saymak daha fazla zaman alabilir.


0

Ben PHP kullanarak TABLOLAR ve TÜM KAYIT saymak budur:

$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.";

Verileri yoksayarsanız neden count (*) kullanmıyorsunuz?
Svetoslav Marinov

0

Poster, saymadan satır sayımı istedi, ancak hangi tablo motorunu belirtmedi. InnoDB ile, sadece bir yol biliyorum, bu sayılacak.

Patateslerimi şu şekilde seçiyorum:

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

Bu konuda herhangi bir iddia yapıyorum, bu gerçekten çirkin ama etkili bir yolu var ne kadar tablo motoru ne olursa olsun veritabanında her tabloda kaç satır var saklı yordamlar yükleme izni gerek kalmadan ve yüklemeye gerek kalmadan yakut veya php. Evet, paslı. Evet önemlidir. count (*) doğrudur.


0

Yukarıdaki @ Nathan'ın cevabına dayanarak, "son birliği kaldırmaya" gerek kalmadan ve çıktıyı sıralama seçeneğiyle aşağıdaki SQL'i kullanıyorum. Daha sonra sadece çalışan başka bir SQL ifadesi oluşturur:

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_lenSunucu değişkeninin yeterince büyük bir değerine ihtiyacınız vardır, ancak MariaDb 10.2.4 sürümünden varsayılan olarak 1M olmalıdır.


0

Aşağıdaki kod, tüm masallar için seçme sorgusu oluşturur. Sadece son "UNION ALL" tüm sonucu seçin ve çalıştırmak için yeni bir sorgu penceresi yapıştırın.

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

Kesin sayıları istiyorsanız, aşağıdaki yakut komut dosyasını kullanın. Ruby ve RubyGems'e ihtiyacınız var.

Aşağıdaki Gems yükleyin:

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

Dosya: 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

Komut satırına geri dönün:

$> ruby count_table_records.rb

Çıktı:

Table users has 7328974 rows.

-4

Tablo sayısını ve adlarını biliyorsanız ve her birinin birincil anahtarları olduğunu varsayarsak COUNT(distinct [column]), her bir tablodan gelen satırları almak için ile birlikte bir birleştirme kullanabilirsiniz :

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

İşte bir SQL Fiddle örneği.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.