【问题标题】:MySQL: Summarize all table row-counts in a single queryMySQL:在单个查询中汇总所有表行数
【发布时间】:2014-09-02 16:10:59
【问题描述】:

查看数据库时,了解所有表的概览(包括它们的行数)非常有用:

TableName    Count
t1           1234
t2             37 
...           ...

information_schema 数据库中的 MySQL TABLES 表提供了一个 table_rows 字段:

SELECT table_name, table_rows
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_SCHEMA = '<your db>';

但是 table_rows 仅对某些数据库引擎有效,而对于 INNODB 则为 NULL 或不准确。

因此,有必要编写一个为每个表执行显式 SELECT Count(*)... 的方法。

在 stackoverflow 上多次重复此问题时,有许多答案涉及两步过程。一个查询创建一个结果集,其中的行包含各个 select count(*) 语句,然后是一个文本编辑过程,将其转换为可以产生所需输出的实际语句。

我还没有看到这变成了一个步骤,所以我在下面发布了这个答案。这不是火箭科学,但写出来很方便。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    这里的第一个示例代码是一个存储过程,就用户而言,它一步完成整个过程。

    BEGIN
    
    # zgwp_tables_rowcounts
    # TableName RowCount
    # Outputs a result set listing all tables and their row counts 
    # for the current database
    
    SET SESSION group_concat_max_len = 1000000;
    
    SET @sql = NULL;
    SET @dbname = DATABASE();
    
    SELECT
      GROUP_CONCAT( 
        CONCAT (
          'SELECT ''',table_name,''' as TableName, COUNT(*) as RowCount FROM ', 
           table_name, ' '
        ) 
        SEPARATOR 'UNION '  
      ) AS Qry
    FROM
      information_schema.`TABLES` AS t
    WHERE
      t.TABLE_SCHEMA = @dbname AND
      t.TABLE_TYPE = "BASE TABLE"
    ORDER BY
      t.TABLE_NAME ASC
    
    INTO @sql
    ;
    
    PREPARE stmt FROM @sql;
    
    EXECUTE stmt;
    
    END
    

    注意事项:

    • SELECT..INTO @sql 创建必要的查询,然后 PREPARE...EXECUTE 运行它。

    • 设置 group_concat_max_len 变量以允许来自 GROUP_CONCAT 的足够长的结果字符串。

    上述过程对于在 Navicat 等管理环境或命令行中快速查看很有用。然而,尽管返回了一个结果集,据我所知,它不能在另一个视图或查询中被引用,大概是因为 MySQL 在运行它之前无法确定它产生什么结果集,更不用说它们有什么列了.

    因此,无需手动编辑即可快速生成可用作视图的单独 SELECT...UNION 语句仍然很有用。如果您想将行数连接到另一个表中的其他一些每个表的信息,这很有用。这里还有另一个存储过程:

    BEGIN
    
    # zgwp_tables_rowcounts_view_statement
    # Output: SelectStatement
    # Outputs a single row and column, containing a (possibly lengthy)
    # SELECT...UNION statement that, if used as a View, will output
    # TableName RowCount for all tables in the current database.
    
    SET SESSION group_concat_max_len = 1000000;
    SET @dbname = DATABASE();
    
    SELECT
      GROUP_CONCAT( 
        CONCAT (
          'SELECT ''',table_name,''' as TableName, COUNT(*) as RowCount FROM ', 
          table_name, ' ', CHAR(10)) 
        SEPARATOR 'UNION '  
      ) AS SelectStatement
    FROM
      information_schema.`TABLES` AS t
    WHERE
      t.TABLE_SCHEMA = @dbname AND
      t.TABLE_TYPE = "BASE TABLE"
    ORDER BY
      t.TABLE_NAME ASC
    ;
    END
    

    注意事项

    • 在概念上与第一个过程非常相似。为了方便查看或编辑语句,我在每个子“SELECT...UNION”语句中添加了换行符 (CHAR(10))。

    • 如果这对您的环境更方便,您可以将其创建为函数并返回 SelectStatement。

    希望对您有所帮助。

    【讨论】:

    • 这太棒了!一个小的更正是在CONCAT 中第二次出现table_name 周围添加反引号。这使得这也适用于具有“非法”字符的表名(由于某些遗留原因,我有一个名称中包含 -2s 的表,这破坏了您的解决方案。由于此处的格式限制,提供示例有点困难。
    • @Joep 是的,我知道这会有什么帮助。感谢您加入这个想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2012-10-08
    • 2021-11-12
    • 1970-01-01
    相关资源
    最近更新 更多