Abrufen der Datensatzanzahl für alle Tabellen in der MySQL-Datenbank
347
Gibt es eine Möglichkeit, die Anzahl der Zeilen in allen Tabellen in einer MySQL-Datenbank zu ermitteln, ohne SELECT count()für jede Tabelle eine auszuführen ?
Erweiterte Antwort, die auch für InnoDB korrekt ist
gwideman
1
SELECT count (table_name) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'YOUR_DB' gibt die Anzahl der Tabellen in Ihrer Datenbank an
shasi kanth
Antworten:
416
SELECT SUM(TABLE_ROWS)FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA ='{your_db}';
Hinweis aus den Dokumenten: Bei InnoDB-Tabellen ist die Zeilenanzahl nur eine grobe Schätzung, die bei der SQL-Optimierung verwendet wird. Sie müssen COUNT (*) für genaue Zählungen verwenden (was teurer ist).
Jaitsu, nein ist es nicht. count (*) (oder realistischer count (id)) ist das, was MySQL verwendet, um seine Zeilen zu zählen, nicht wahr? Auf jeden Fall habe ich es gerade getestet und eine größere Nummer für den Aufruf von count () bekommen, was auch immer das wert ist.
Codygman
2
SELECT TABLE_NAME, SUM (TABLE_ROWS) N FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}' Gruppe nach TABLE_NAME;
PiyusG
175
Sie können wahrscheinlich etwas mit Tabellen Tabelle zusammenstellen . Ich habe es noch nie gemacht, aber es sieht so aus, als hätte es eine Spalte für TABLE_ROWS und eine für TABLE NAME .
Um Zeilen pro Tabelle abzurufen, können Sie eine Abfrage wie die folgende verwenden:
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA ='**YOUR SCHEMA**';
Gibt es eine andere Möglichkeit, table_row und table_name abzurufen? Weil ich ein genaues Ergebnis will, keine grobe Schätzung. Vielen Dank.
Krunal Shah
1
Wie Kuranl erwähnte, gibt dies nur eine Schätzung zurück und wird wahrscheinlich unterschiedliche Ergebnisse liefern, wenn es ein paar Mal ausgeführt wird
Kris
Tabellen mit mindestens ~ 250 Datensätzen scheinen bei jeder Ausführung dieser Abfrage eine andere Anzahl von Zeilen zu melden.
Arthur
Hoppla ... wünschte, ich hätte das Wort "Geschätzt" schon vorher gesehen ... wie gestern! Sollte die Antwort nicht abgelehnt werden? Da OP nicht nach "geschätzt" gefragt hat und es albern erscheint zu denken, dass er vielleicht eine Schätzung will. "Schätzung" Könnten Kastanienbraune wie ich davor bewahren, die "Schätzung" zu verpassen?
Kreeverp
111
Wie @Venkatramanan und andere fand ich INFORMATION_SCHEMA.TABLES unzuverlässig (unter Verwendung von InnoDB, MySQL 5.1.44) und gab jedes Mal, wenn ich es auch in stillgelegten Tabellen ausführe, unterschiedliche Zeilenzahlen an. Hier ist eine relativ hackige (aber flexible / anpassbare) Möglichkeit, eine große SQL-Anweisung zu generieren, die Sie in eine neue Abfrage einfügen können, ohne Ruby-Edelsteine und andere Dinge zu installieren.
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**';
Es erzeugt eine Ausgabe wie folgt:
SELECT"func"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.func UNIONSELECT"general_log"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.general_log UNIONSELECT"help_category"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.help_category UNIONSELECT"help_keyword"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.help_keyword UNIONSELECT"help_relation"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.help_relation UNIONSELECT"help_topic"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.help_topic UNIONSELECT"host"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.host UNIONSELECT"ndb_binlog_index"AS table_name, COUNT(*)AS exact_row_count FROM my_schema.ndb_binlog_index UNION
Kopieren und Einfügen mit Ausnahme der letzten UNION, um eine schöne Ausgabe zu erhalten wie:
Danke, ich hatte gehofft, ich müsste keine Plugins / Gems installieren, um genaue Zählungen zu erhalten.
Bradvido
Die Ausführung dauert bei einer großen Anzahl von Tabellen in der Datenbank zu lange.
Ollamh
1
Fügen Sie am Ende der generierten Abfrage nach dem Entfernen der letzten UNION "select * from (" am Anfang und ") als Ausgabereihenfolge von sure_row_count desc" hinzu, um die Reihenfolge nach Tabellenanzahl desc zu erhalten
Raghavendra
So schließen Sie Ansichten aus: WHERE table_schema = ' my_schema ' und TABLE_TYPE LIKE '% TABLE%'
Watson
38
Ich renne einfach:
show table status;
Auf diese Weise erhalten Sie die Zeilenanzahl für JEDE Tabelle sowie eine Reihe weiterer Informationen. Ich habe die oben ausgewählte Antwort verwendet, aber das ist viel einfacher.
Ich bin nicht sicher, ob dies mit allen Versionen funktioniert, aber ich verwende 5.5 mit InnoDB-Engine.
Wenn Sie InnoDB verwenden, weist dieser Ansatz leider dieselben Ungenauigkeiten auf wie die anderen oben beschriebenen Methoden. Zum Beispiel habe ich eine InnoDB-Tabelle mit ungefähr 65.000 Zeilen, aber diese Methoden hier berichten, dass sie zwischen 350.000 und über 780.000 hat.
PeterToTheThird
Für eine Datenbank mit wenigen Zeilen ist sie ziemlich genau (oder genau genug für meine Anforderungen). Es gab mir 1086 Zeilen für eine Tabelle, die COUNT (*) 904 Zeilen meldete.
Magne
Mit Abstand beste Antwort. Ich benutze InnoDB, aber ich brauche nur einen schnellen Befehl, um die Größenordnung zu kennen.
Nemo
Im Ernst, ich wünschte, dies würde akzeptiert. Ich benutze InnoDB nicht und gebe mir eine genaue Antwort.
Kolob Canyon
1
Die Zeilennummer ist nicht korrekt, aber "Auto_increment" kann Ihnen eine genaue Nummer geben, wenn Sie keine Zeilen aus solchen Tabellen gelöscht haben.
Peter T.
13
SELECT TABLE_NAME,SUM(TABLE_ROWS)FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA ='your_db'GROUPBY TABLE_NAME;
erzeugt geschätzte Tabellenzeilen - vergleiche mit "mysql_num_rows ($ tableresult)"
Kreeverp
1
Das ist eigentlich die beste Antwort! Auch die einfachere Ausführung von mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
MySQL Cli
11
Diese gespeicherte Prozedur listet Tabellen auf, zählt Datensätze und erzeugt am Ende eine Gesamtzahl von Datensätzen.
So führen Sie es nach dem Hinzufügen dieses Verfahrens aus:
CALL `COUNT_ALL_RECORDS_BY_TABLE`();
- -
Der Ablauf:
DELIMITER $$CREATE DEFINER=`root`@`127.0.0.1`PROCEDURE`COUNT_ALL_RECORDS_BY_TABLE`()BEGINDECLARE done INT DEFAULT0;DECLARE TNAME CHAR(255);DECLARE table_names CURSORforSELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA =DATABASE();DECLARECONTINUE HANDLER FORNOT FOUND SET done =1;OPEN table_names;DROPTABLEIFEXISTS 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 =0THENSET@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;ENDIF;ENDWHILE;CLOSE table_names;SELECT*FROM TCOUNTS;SELECT SUM(RECORD_COUNT)AS TOTAL_DATABASE_RECORD_CT FROM TCOUNTS;END
Es gibt eine Art Hack / Workaround für dieses Schätzungsproblem.
Auto_Increment - Aus irgendeinem Grund wird dadurch eine viel genauere Zeilenanzahl für Ihre Datenbank zurückgegeben, wenn für Tabellen ein automatisches Inkrement eingerichtet wurde.
Dies wurde festgestellt, als untersucht wurde, warum die Tabelleninformationen nicht mit den tatsächlichen Daten übereinstimmen.
Sie können dann problemlos PHP oder was auch immer verwenden, um das Maximum der 2 Datenspalten zurückzugeben und die "beste Schätzung" für die Zeilenanzahl zu erhalten.
Bei der automatischen Inkrementierung sind immer +1 * (Tabellenanzahl) Zeilen deaktiviert, aber selbst bei 4.000 Tabellen und 3 Millionen Zeilen ist die Genauigkeit 99,9%. Viel besser als die geschätzten Zeilen.
Das Schöne daran ist, dass die in performance_schema zurückgegebenen Zeilenzahlen auch für Sie gelöscht werden, da das Größte bei Nullen nicht funktioniert. Dies kann jedoch ein Problem sein, wenn Sie keine Tabellen mit automatischer Inkrementierung haben.
Sie können dies versuchen. Es funktioniert gut für mich.
SELECT IFNULL(table_schema,'Total')"Database",TableCount
FROM(SELECT COUNT(1) TableCount,table_schema
FROM information_schema.tables
WHERE table_schema NOTIN('information_schema','mysql')GROUPBY table_schema WITH ROLLUP) A;
Wenn Sie die Datenbank information_schema verwenden, können Sie diesen MySQL-Code verwenden (der where-Teil bewirkt, dass in der Abfrage keine Tabellen mit einem Nullwert für Zeilen angezeigt werden):
Die folgende Abfrage erzeugt eine (weitere) Abfrage, die den Wert von count (*) für jede Tabelle aus jedem in information_schema.tables aufgelisteten Schema erhält. Das gesamte Ergebnis der hier gezeigten Abfrage - alle Zeilen zusammengenommen - enthält eine gültige SQL-Anweisung, die mit einem Semikolon endet - keine baumelnde 'Vereinigung'. Die baumelnde Vereinigung wird durch die Verwendung einer Vereinigung in der folgenden Abfrage vermieden.
select concat('select "', table_schema,'.', table_name,'" as `schema.table`,
count(*)
from ', table_schema,'.', table_name,' union ')as'Query Row'from information_schema.tables
unionselect'(select null, null limit 0);';
Dies ist, was ich tue, um die tatsächliche Anzahl zu erhalten (keine Verwendung des Schemas)
Es ist langsamer, aber genauer.
Es ist ein zweistufiger Prozess bei
Holen Sie sich eine Liste der Tabellen für Ihre Datenbank. Sie können es mit bekommen
mysql -uroot -p mydb -e "show tables"
Erstellen Sie die Liste der Tabellen und weisen Sie sie der Array-Variablen in diesem Bash-Skript zu (getrennt durch ein einzelnes Leerzeichen, genau wie im folgenden Code).
array=( table1 table2 table3 )for i in"${array[@]}"
do
echo $i
mysql -uroot mydb -e "select count(*) from $i"
done
Eine weitere Option: Für Nicht-InnoDB werden Daten aus information_schema.TABLES verwendet (da es schneller ist), für InnoDB wählen Sie count (*), um die genaue Anzahl zu erhalten. Außerdem werden Ansichten ignoriert.
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;
Wenn Ihre Datenbank viele große InnoDB-Tabellen enthält, kann das Zählen aller Zeilen länger dauern.
Warum verwenden Sie nicht count (*), wenn Sie die Daten ignorieren?
Svetoslav Marinov
0
Das Poster wollte die Anzahl der Zeilen ohne zu zählen, gab jedoch nicht an, welche Tabellen-Engine verwendet wurde. Mit InnoDB kenne ich nur einen Weg, nämlich zu zählen.
So pflücke ich meine Kartoffeln:
# Put this functionin your bash and call with:# rowpicker DBUSER DBPASS DBNAME [TABLEPATTERN]function rowpicker(){
UN=$1
PW=$2
DB=$3if[!-z "$4"];then
PAT="LIKE '$4'"
tot=-2else
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"}
Ich mache keine Aussagen darüber, außer dass dies ein wirklich hässlicher, aber effektiver Weg ist, um zu ermitteln, wie viele Zeilen in jeder Tabelle in der Datenbank vorhanden sind, unabhängig von der Tabellen-Engine und ohne die Berechtigung zum Installieren gespeicherter Prozeduren und ohne Installation Rubin oder PHP. Ja, es ist rostig. Ja, es zählt. count (*) ist korrekt.
Basierend auf der obigen Antwort von @ Nathan, aber ohne "die endgültige Vereinigung entfernen zu müssen" und mit der Option, die Ausgabe zu sortieren, verwende ich das folgende SQL. Es wird eine weitere SQL-Anweisung generiert, die dann einfach ausgeführt wird:
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
Sie benötigen einen ausreichend großen Wert für die group_concat_max_lenServervariable, aber ab MariaDb 10.2.4 sollte standardmäßig 1 MB verwendet werden.
Der folgende Code generiert die Auswahlabfrage für alle Geschichten. Löschen Sie einfach das letzte "UNION ALL", wählen Sie alle Ergebnisse aus und fügen Sie ein neues Abfragefenster ein, das ausgeführt werden soll.
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'
Wenn Sie die Anzahl der Tabellen und ihre Namen kennen und davon ausgehen, dass sie jeweils Primärschlüssel haben, können Sie einen Cross-Join in Kombination mit verwenden COUNT(distinct [column]), um die Zeilen abzurufen, die aus jeder Tabelle stammen:
Antworten:
Hinweis aus den Dokumenten: Bei InnoDB-Tabellen ist die Zeilenanzahl nur eine grobe Schätzung, die bei der SQL-Optimierung verwendet wird. Sie müssen COUNT (*) für genaue Zählungen verwenden (was teurer ist).
quelle
Sie können wahrscheinlich etwas mit Tabellen Tabelle zusammenstellen . Ich habe es noch nie gemacht, aber es sieht so aus, als hätte es eine Spalte für TABLE_ROWS und eine für TABLE NAME .
Um Zeilen pro Tabelle abzurufen, können Sie eine Abfrage wie die folgende verwenden:
quelle
Wie @Venkatramanan und andere fand ich INFORMATION_SCHEMA.TABLES unzuverlässig (unter Verwendung von InnoDB, MySQL 5.1.44) und gab jedes Mal, wenn ich es auch in stillgelegten Tabellen ausführe, unterschiedliche Zeilenzahlen an. Hier ist eine relativ hackige (aber flexible / anpassbare) Möglichkeit, eine große SQL-Anweisung zu generieren, die Sie in eine neue Abfrage einfügen können, ohne Ruby-Edelsteine und andere Dinge zu installieren.
Es erzeugt eine Ausgabe wie folgt:
Kopieren und Einfügen mit Ausnahme der letzten UNION, um eine schöne Ausgabe zu erhalten wie:
quelle
Ich renne einfach:
Auf diese Weise erhalten Sie die Zeilenanzahl für JEDE Tabelle sowie eine Reihe weiterer Informationen. Ich habe die oben ausgewählte Antwort verwendet, aber das ist viel einfacher.
Ich bin nicht sicher, ob dies mit allen Versionen funktioniert, aber ich verwende 5.5 mit InnoDB-Engine.
quelle
Das ist alles was du brauchst.
quelle
mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
Diese gespeicherte Prozedur listet Tabellen auf, zählt Datensätze und erzeugt am Ende eine Gesamtzahl von Datensätzen.
So führen Sie es nach dem Hinzufügen dieses Verfahrens aus:
- -
Der Ablauf:
quelle
Einfacher Weg:
Ergebnisbeispiel:
quelle
Es gibt eine Art Hack / Workaround für dieses Schätzungsproblem.
Auto_Increment - Aus irgendeinem Grund wird dadurch eine viel genauere Zeilenanzahl für Ihre Datenbank zurückgegeben, wenn für Tabellen ein automatisches Inkrement eingerichtet wurde.
Dies wurde festgestellt, als untersucht wurde, warum die Tabelleninformationen nicht mit den tatsächlichen Daten übereinstimmen.
Sie können dann problemlos PHP oder was auch immer verwenden, um das Maximum der 2 Datenspalten zurückzugeben und die "beste Schätzung" für die Zeilenanzahl zu erhalten.
dh
Bei der automatischen Inkrementierung sind immer +1 * (Tabellenanzahl) Zeilen deaktiviert, aber selbst bei 4.000 Tabellen und 3 Millionen Zeilen ist die Genauigkeit 99,9%. Viel besser als die geschätzten Zeilen.
Das Schöne daran ist, dass die in performance_schema zurückgegebenen Zeilenzahlen auch für Sie gelöscht werden, da das Größte bei Nullen nicht funktioniert. Dies kann jedoch ein Problem sein, wenn Sie keine Tabellen mit automatischer Inkrementierung haben.
quelle
Sie können dies versuchen. Es funktioniert gut für mich.
quelle
Wenn Sie die Datenbank information_schema verwenden, können Sie diesen MySQL-Code verwenden (der where-Teil bewirkt, dass in der Abfrage keine Tabellen mit einem Nullwert für Zeilen angezeigt werden):
quelle
Die folgende Abfrage erzeugt eine (weitere) Abfrage, die den Wert von count (*) für jede Tabelle aus jedem in information_schema.tables aufgelisteten Schema erhält. Das gesamte Ergebnis der hier gezeigten Abfrage - alle Zeilen zusammengenommen - enthält eine gültige SQL-Anweisung, die mit einem Semikolon endet - keine baumelnde 'Vereinigung'. Die baumelnde Vereinigung wird durch die Verwendung einer Vereinigung in der folgenden Abfrage vermieden.
quelle
Dies ist, was ich tue, um die tatsächliche Anzahl zu erhalten (keine Verwendung des Schemas)
Es ist langsamer, aber genauer.
Es ist ein zweistufiger Prozess bei
Holen Sie sich eine Liste der Tabellen für Ihre Datenbank. Sie können es mit bekommen
Erstellen Sie die Liste der Tabellen und weisen Sie sie der Array-Variablen in diesem Bash-Skript zu (getrennt durch ein einzelnes Leerzeichen, genau wie im folgenden Code).
Starte es:
quelle
Eine weitere Option: Für Nicht-InnoDB werden Daten aus information_schema.TABLES verwendet (da es schneller ist), für InnoDB wählen Sie count (*), um die genaue Anzahl zu erhalten. Außerdem werden Ansichten ignoriert.
Wenn Ihre Datenbank viele große InnoDB-Tabellen enthält, kann das Zählen aller Zeilen länger dauern.
quelle
So zähle ich TABELLEN und ALLE AUFZEICHNUNGEN mit PHP:
quelle
Das Poster wollte die Anzahl der Zeilen ohne zu zählen, gab jedoch nicht an, welche Tabellen-Engine verwendet wurde. Mit InnoDB kenne ich nur einen Weg, nämlich zu zählen.
So pflücke ich meine Kartoffeln:
Ich mache keine Aussagen darüber, außer dass dies ein wirklich hässlicher, aber effektiver Weg ist, um zu ermitteln, wie viele Zeilen in jeder Tabelle in der Datenbank vorhanden sind, unabhängig von der Tabellen-Engine und ohne die Berechtigung zum Installieren gespeicherter Prozeduren und ohne Installation Rubin oder PHP. Ja, es ist rostig. Ja, es zählt. count (*) ist korrekt.
quelle
Basierend auf der obigen Antwort von @ Nathan, aber ohne "die endgültige Vereinigung entfernen zu müssen" und mit der Option, die Ausgabe zu sortieren, verwende ich das folgende SQL. Es wird eine weitere SQL-Anweisung generiert, die dann einfach ausgeführt wird:
Sie benötigen einen ausreichend großen Wert für die
group_concat_max_len
Servervariable, aber ab MariaDb 10.2.4 sollte standardmäßig 1 MB verwendet werden.quelle
Der folgende Code generiert die Auswahlabfrage für alle Geschichten. Löschen Sie einfach das letzte "UNION ALL", wählen Sie alle Ergebnisse aus und fügen Sie ein neues Abfragefenster ein, das ausgeführt werden soll.
quelle
Wenn Sie die genauen Zahlen möchten, verwenden Sie das folgende Ruby-Skript. Sie benötigen Ruby und RubyGems.
Installiere folgende Edelsteine:
Datei: count_table_records.rb
Gehen Sie zurück zur Befehlszeile:
Ausgabe:
quelle
Wenn Sie die Anzahl der Tabellen und ihre Namen kennen und davon ausgehen, dass sie jeweils Primärschlüssel haben, können Sie einen Cross-Join in Kombination mit verwenden
COUNT(distinct [column])
, um die Zeilen abzurufen, die aus jeder Tabelle stammen:Hier ist ein SQL Fiddle- Beispiel.
quelle