MySQL数据库中所有行的准确计数

11

我目前正在使用该脚本

SELECT SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'Tables';

然而,这并不准确,因为我的MySQL表所使用的引擎是InnoDB(我现在才意识到这可能是一个问题,因为这些数据库已经存在一段时间了)。

有没有办法在MySQL中精确计算每个表中每行的数量?

谢谢。


因为我在示例中不小心掉了一个“s”。实际上,我需要计算特定数据库中所有表的行数。 - Connor Deckers
扩展答案:https://dev59.com/A2Af5IYBdhLWcg3wZB6u - gwideman
2
这不是https://dev59.com/tnE85IYBdhLWcg3wnU0d的重复。这个问题特别询问具有InnoDB表的数据库。 - g-dog
6个回答

14

我认为唯一精确(但速度较慢)的方法是针对每个单独的表进行操作:

SELECT COUNT(*) FROM Table

@vearutop 在他/她的回答中提到,这需要在每个表上运行... - Ben Swinburne
2
我不会把所有东西都放在SQL查询中,因为似乎MySQL无法从变量表名中进行选择。所以我至少想到了查询生成器:SELECT CONCAT('SELECT COUNT(*) FROM ', table_name) FROM information_schema.tables WHERE table_schema = 'Tables'; - jkrcma
谢谢 @DragonJake,结果就是我必须这样做。 :) - Connor Deckers

5
这个SQL语句将生成一个联合查询,可以在一步中完成任务:
SELECT CONCAT('SELECT \'', table_name ,'\' as tbl, (SELECT COUNT(*) FROM ', table_name, ') AS ct UNION')
FROM information_schema.tables
WHERE table_schema = 'your_database';

运行SQL语句后,将输出粘贴到文本编辑器中,删除输出末尾的“UNION”单词,即可得到联合查询。

请注意,运行联合查询可能会消耗大量资源,具体取决于您的数据库大小、负载和硬件配置,因此您可能不希望一次性运行它。


3

我遇到了同样的问题,所以来到这个问题。

感谢computerGuy12345的回答,我写了一个存储过程来完成这个操作,而不需要复制粘贴。正如他所说的那样,请注意这将扫描每个表,并可能需要一些时间。

DELIMITER $$

CREATE PROCEDURE `all_tables_rowcount`(databaseName VARCHAR(250))
BEGIN
DECLARE p_done INT DEFAULT FALSE;
DECLARE p_queryString varchar(250) ;
DECLARE p_cur CURSOR FOR SELECT queryString FROM tmp.tableCountQueries;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET p_done = TRUE;

DROP TEMPORARY TABLE IF EXISTS tmp.tableCountQueries;
DROP TEMPORARY TABLE IF EXISTS tmp.tableCounts;

CREATE TEMPORARY TABLE tmp.tableCounts(TableName varchar(250), RowCount BIGINT) ;

CREATE TEMPORARY TABLE tmp.tableCountQueries(queryString varchar(250)) AS 
(
    SELECT CONCAT(
        'INSERT INTO tmp.tableCounts(TableName, RowCount) SELECT "', 
        table_name, 
        '", COUNT(*) AS RowCount FROM ', 
        table_schema,
        '.',
        table_name
    ) AS queryString
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE table_schema = databaseName
) ;

OPEN p_cur;

read_loop: LOOP
    FETCH p_cur INTO p_queryString;
    IF p_done THEN
      LEAVE read_loop;
    END IF;
    SET @queryString = p_queryString ;
    PREPARE rowcountTable FROM @queryString; 
    EXECUTE rowcountTable ;
END LOOP;

SELECT * FROM tmp.tableCounts ;
END

这非常有帮助。谢谢! - Manny Calavera

1

Select Sum(column_Name) from table 无法准确计算表中的行数,它会返回总行数+1,也就是下一个插入数据的行。另外需要注意的是,在 sum(Column_Name) 中,column_Name 应该是 int 类型,如果是 varchar 或 char 类型,则 sum 函数将无法正常工作。因此,最好使用 Select Count(*) from table 来获取表中的确切行数。

谢谢,

Venkat


1
select table_name,table_rows from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='database name';

table_name 指的是“数据表”中存在的表数目。

table_rows 指的是每个列中的行数。

table_schema 是数据库名称。从哪个数据库中查找计数。


2
INFORMATION_SCHEMA中的table_rows计数对于Innodb表并不准确,它只是一个近似值。 - forforf
1
同意。这对于非InnoDB表是有效的,但并没有解决具体问题。 - g-dog

-2

这对我有用

    <?php 

             mysql_connect("localhost", "root", "pass") or die(mysql_error());

             mysql_select_db("csl") or die(mysql_error());

             $dtb=mysql_query("SHOW TABLES") or die (mysql_error()); 

             $jmltbl=0; $jml_record=0; $jml_record=0; $total =0;


             while($row=mysql_fetch_array($dtb)) 

    { 

 $sql=mysql_query("select * from $row[0]");

 $jml_record=mysql_num_rows($sql);

 $total += $jml_record;   // this counts all the rows





 $jmltbl++; $jml_record+=$jml_record;




    } 
      // echo"--------$jmltbl Tables, $jml_record records."; // will print count of indivual table

echo $total;  // this will print you count of all rows in MySQL database 

       ?>

我已经测试了这段代码,它可以正常工作。

对我来说输出是1145。


对我来说,它并不慢,它立即计算出了1145。其他与模式相关的场景对我来说都无法工作,它们只会给出空结果。 - Rinzler
1
-1 表示返回整个数据库中所有表的所有行。请使用 count(*) 代替 * - dotancohen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接