获取MySQL数据库中所有表的logging数

有没有一种方法来获取MySQL数据库中的所有表中的行数,而无需在每个表上运行SELECT count()

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

但是从文档中注意到:对于InnoDB表, 行计数只是 SQL优化中使用的粗略估计 。 您需要使用COUNT(*)进行确切的计数(这是更昂贵的)。

你可以把表格放在一起。 我从来没有做过,但它看起来像有一个TABLE_ROWS列和一个TABLE NAME列

要获取每个表的行数,可以使用如下查询:

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

像@Venkatramanan和其他人一样,我发现INFORMATION_SCHEMA.TABLES不可靠(使用InnoDB,MySQL 5.1.44),即使在静默表上运行它也会给出不同的行数。 这里有一个相对而言(但灵活/适应性强)的方式来生成一个大的SQL语句,您可以粘贴到一个新的查询,而无需安装Ruby的gem和东西。

 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; 

这会给你每行表加上一堆其他信息的行数。 我曾经使用上面的select的答案,但这是更容易。

我不确定这是否适用于所有版本,但是我使用的是InnoDB引擎。

该存储过程列出表格,计数logging,并在最后生成总logging数。

在添加此过程之后运行它:

 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 
  SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your_db' GROUP BY TABLE_NAME; 

这就是你所需要的。

如果您使用数据库information_schema,则可以使用此mysql代码(where部分使查询不显示具有空值的表的行):

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

你可以试试这个 它对我来说工作得很好。

 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; 

以下查询生成一个(nother)查询,它将从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);'; 

如果你想要确切的数字,使用下面的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. 

这是我如何使用PHP计算表和所有logging:

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

海报希望行数不计算,但没有指定哪个表引擎。 有了InnoDB,我只知道一个方法,就是数一数。

这是我如何select我的土豆:

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

我没有断言这是另一个,这是一个非常丑陋,但有效的方式来获取有多less行存在于数据库的每个表中,无论表引擎,并且没有权限安装存储的过程,并且不需要安装ruby或PHP。 是的,它生锈。 是的,它很重要。 计数(*)是准确的。

这是我所做的实际计数(不使用架构)

速度较慢,但​​更准确。

这是一个两步的过程

  1. 获取你的数据库表的列表。 你可以使用它

     mysql -uroot -p mydb -e "show tables" 
  2. 在这个bash脚本中创build表格并将其分配给数组variables(如下面的代码所示,由一个空格分隔)

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

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

还有一个select:对于非InnoDB,它使用来自information_schema.TABLES的数据(因为它更快),对于InnoDB,selectcount(*)来获得准确的计数。 它也忽略了意见。

 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; 

如果你的数据库有很多大InnoDB表计算所有的行可能需要更多的时间。

对于这个估算问题,有一些解决办法。

Auto_Increment – 出于某种原因,如果您在表上设置了自动增量,则会为您的数据库返回更准确的行数。

在探索show table信息与实际数据不匹配时发现这一点。

 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个表和3百万行,这也是99.9%的准确度。 比估计的行好得多。

这样做的好处在于,在performance_schema中返回的行数也会被删除,因为最大值对于空值不起作用。 这可能是一个问题,如果你没有自动增量的表,但是。

如果您知道表的数量及其名称,并假设它们各自都有主键,则可以将COUNT(distinct [column])COUNT(distinct [column])结合使用交叉联接,以获取来自每个表的行:

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

这是一个SQL小提琴示例。