是否有一种方法可以获得MySQL数据库中所有表的行计数,而无需在每个表上运行SELECT count() ?
当前回答
我只是跑:
show table status;
这将为您提供每个表的行数以及其他一些信息。 我曾经使用上面选择的答案,但这要简单得多。
我不确定这是否适用于所有版本,但我使用5.5与InnoDB引擎。
其他回答
SELECT SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{your_db}';
从文档中注意到:对于InnoDB表,行数只是用于SQL优化的粗略估计。您需要使用COUNT(*)来获得精确的计数(成本更高)。
还有一个选择:对于非InnoDB,它使用information_schema中的数据。TABLES(因为它更快),对于InnoDB -选择count(*)来获得准确的计数。它还会忽略视图。
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表,计算所有行会花费更多的时间。
像许多其他人一样,我很难用InnoDB在INFORMATION_SCHEMA表上获得准确的值,并且能够通过count()进行查询将无限受益,并且希望在一次查询中完成它。
首先,确保启用大规模group_concats:
SET SESSION group_concat_max_len = 1000000;
然后运行此查询以获得将为数据库运行的结果查询。
SELECT CONCAT('SELECT ', GROUP_CONCAT(table1.count SEPARATOR ',\n')) FROM (
SELECT concat('(SELECT count(id) AS \'',table_name,' Count\' ','FROM ',table_name,') AS ',table_name,'_Count') AS 'count'
FROM information_schema.tables
WHERE table_schema = '**YOUR_DATABASE_HERE**'
) AS table1
这将生成诸如…
SELECT (SELECT count(id) AS 'table1 Count' FROM table1) AS table1_Count,
(SELECT count(id) AS 'table2 Count' FROM table2) AS table2_Count,
(SELECT count(id) AS 'table3 Count' FROM table3) AS table3_Count;
这反过来又产生了以下结果:
*************************** 1. row ***************************
table1_Count: 1
table2_Count: 1
table3_Count: 0
下面的查询生成一个(另一个)查询,该查询将从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);';
对于这个估算问题,有一点hack/workaround。
Auto_Increment -由于某些原因,如果您在表上设置了自动增量,则此函数将为数据库返回更准确的行数。
在探索为什么显示表信息与实际数据不匹配时发现了这一点。
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;
Auto Increment将始终是+1 *(表数)行,但即使有4000个表和300万行,这也是99.9%的准确性。比估计的行数好多了。
这样做的好处是,performance_schema中返回的行计数也会被擦除,因为greatest对null无效。但是,如果没有带有自动递增功能的表,这可能是个问题。
推荐文章
- 在MySQL中的一个查询中更新多个具有不同值的行
- 如果表存在则删除表并创建它,如果不存在则创建它
- 在SQL中更新多个列
- 如何删除表中特定列的第一个字符?
- MySQL OR与IN性能
- 哪个更快/最好?SELECT *或SELECT columnn1, colum2, column3等
- 将值从同一表中的一列复制到另一列
- GROUP BY with MAX(DATE)
- 删除id与其他表不匹配的sql行
- 等价的限制和偏移SQL Server?
- MySQL CPU使用率高
- INT和VARCHAR主键之间有真正的性能差异吗?
- 拒绝访问;您需要(至少一个)SUPER特权来执行此操作
- 为什么我不能在DELETE语句中使用别名?
- 在SQL Server Management Studio中保存带有标题的结果