MySQL 데이터베이스의 모든 테이블에 대한 레코드 수 확보


347

SELECT count()각 테이블에서 실행하지 않고 MySQL 데이터베이스의 모든 테이블에서 행 수를 얻는 방법이 있습니까?


1
InnoDB에도 정확한 확장 답변 : stackoverflow.com/questions/24707814/…
gwideman

1
SELECT_table (name_name) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'YOUR_DB' 는 데이터베이스의 테이블 수를
나타냅니다

답변:


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

문서의 참고 사항 : InnoDB 테이블의 경우 행 수는 SQL 최적화에 사용되는 대략적인 추정치 입니다. 정확한 수 (더 비싼)를 위해서는 COUNT (*)를 사용해야합니다.


267
또는 각 테이블에 대해 원하는 경우 : SELECT table_name, TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}';
TheSoftwareJedi은

5
table_row 및 table_name을 얻는 다른 방법이 있습니까? 나는 대략적인 추정치가 아닌 정확한 결과를 원하기 때문입니다. 감사합니다.
krunal shah

3
@krunalshah, 이것은 InnoDB의 제한 사항 중 하나입니다. 자세한 내용은 dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html , InnoDB 테이블 제한 섹션을 참조하십시오 . 당신은 항상 SELECT COUNT (*) FROM t를 사용할 수 있지만, 훨씬 느립니다
Marking

2
자 이츠, 아니에요 count (*) (또는보다 현실적인 count (id))는 mysql이 행을 계산하는 데 사용하는 것입니까? 어쨌든 방금 테스트하여 count () 호출에 대한 더 큰 숫자를 얻었습니다.
codygman

2
TABLE_NAME에 의해 INFORMATION_SCHEMA.TABLES에서 TABLE_NAME, SUM (TABLE_ROWS) N 선택 TABLE_SCHEMA = '{your_db}'
PiyusG

176

Tables table 과 함께 무언가를 넣을 수 있습니다 . 나는 그것을 해본 적이 없다,하지만이에 대한 열 것 같습니다 TABLE_ROWS 에 대한 하나의 테이블 이름을 .

테이블 당 행을 얻으려면 다음과 같은 쿼리를 사용할 수 있습니다.

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

4
table_row 및 table_name을 얻는 다른 방법이 있습니까? 나는 대략적인 추정치가 아닌 정확한 결과를 원하기 때문입니다. 감사합니다.
krunal shah

1
kuranl는 추정이 반환을 언급 한 몇 번 실행하면 아마도 다른 결과를 반환으로
크리스

~ 250 개 이상의 레코드가있는 테이블은이 쿼리를 실행할 때마다 다른 행 수를보고하는 것 같습니다.
Arthur

죄송합니다 ... 어제처럼 "예상 됨"이라는 단어를 보았 으면 좋겠어요! 답변을 거부해서는 안됩니까? OP가 "추정"을 요구하지 않았기 때문에 그가 견적을 원한다고 생각하는 것은 어리석은 것 같습니다. "추정"나와 같은 적갈색이 "추정"을 놓치는 것을 막을 수 있습니까?
Kreeverp

111

@Venkatramanan 및 기타와 마찬가지로 INFORMATION_SCHEMA.TABLES를 신뢰할 수 없다는 것을 알았습니다 (InnoDB, MySQL 5.1.44 사용). 다음은 Ruby gem 및 항목을 설치하지 않고 새 쿼리에 붙여 넣을 수있는 큰 SQL 문을 생성하는 비교적 해킹 적이지만 융통성 있고 적응 가능한 방법입니다.

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)

2
고마워, 나는 정확한 수를 얻기 위해 플러그인 / 보석을 설치할 필요가 없기를 바랐다.
bradvido

데이터베이스에 많은 수의 테이블이있는 경우 실행하는 데 시간이 오래 걸립니다.
ollamh

1
테이블 개수를 기준으로 desc를 얻기 위해 마지막 UNION을 제거한 후 생성 된 쿼리의 끝에 "select * from ("(처음에 ""및 "정확한 행에 의한 출력 순서로 count_count desc"를 추가하십시오 ")
Raghavendra

뷰를 제외하려면 WHERE table_schema = ' my_schema '및 TABLE_TYPE LIKE '% TABLE %'
Watson

39

방금 실행합니다.

show table status;

이렇게하면 모든 테이블에 대한 행 수와 다른 많은 정보가 제공됩니다. 위에서 선택한 답변을 사용했지만 훨씬 쉽습니다.

이것이 모든 버전에서 작동하는지 확실하지 않지만 InnoDB 엔진에서 5.5를 사용하고 있습니다.


5
불행하게도, InnoDB를 사용하는 경우,이 방법은 위에서 설명한 다른 방법과 동일한 부정확성을 겪습니다. 예를 들어, 약 65,000 개의 행이있는 InnoDB 테이블이 있지만 여기에서이 방법은 350,000 개에서 780,000 개가 넘는 것으로보고합니다.
PeterToTheThird

행이 적은 DB의 경우 상당히 정확합니다 (또는 내 요구에 충분히 정확합니다). COUNT (*)가 904 개의 행을보고 한 테이블에 대해 1086 개의 행을 제공했습니다.
Magne

가장 좋은 대답입니다. InnoDB를 사용하지만 규모를 알기 위해서는 빠른 명령 만 필요합니다.
니모

진심으로, 이것이 받아 들여지기를 바랍니다. InnoDB를 사용하지 않고 정확한 답변을 제공합니다.
Kolob Canyon 2013

1
행 번호는 정확하지 않지만 "Auto_increment"는 해당 테이블에서 행을 삭제하지 않은 경우 정확한 숫자를 제공 할 수 있습니다.
피터 T.

13
 SELECT TABLE_NAME,SUM(TABLE_ROWS) 
 FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_SCHEMA = 'your_db' 
 GROUP BY TABLE_NAME;

그게 당신이 필요한 전부입니다.


1
예상 테이블 행 생성- "mysql_num_rows ($ tableresult)"와 비교
Kreeverp

1
그것은 실제로 가장 좋은 대답입니다! 또한 mysql cli에서 실행하는 것이 더 간단합니다.mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
loretoparisi

11

이 저장 프로시 저는 테이블을 나열하고 레코드를 계산하며 끝에 총 레코드 수를 생성합니다.

이 절차를 추가 한 후 실행하려면 다음을 수행하십시오.

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

8

간단한 방법 :

SELECT
  TABLE_NAME, SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{Your_DB}'
GROUP BY TABLE_NAME;

결과 예 :

+----------------+-----------------+
| TABLE_NAME     | SUM(TABLE_ROWS) |
+----------------+-----------------+
| calls          |            7533 |
| courses        |             179 |
| course_modules |             298 |
| departments    |              58 |
| faculties      |             236 |
| modules        |             169 |
| searches       |           25423 |
| sections       |             532 |
| universities   |              57 |
| users          |           10293 |
+----------------+-----------------+

4

이 추정 문제에는 약간의 해킹 / 해결 방법이 있습니다.

Auto_Increment-어떤 이유로 테이블에 자동 증분을 설정 한 경우 데이터베이스에 대해 훨씬 정확한 행 수를 반환합니다.

show table info가 실제 데이터와 일치하지 않는 이유를 탐색 할 때이를 발견했습니다.

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에 반환 된 행 개수가 널에서도 지워지지 않는다는 것입니다. 그러나 자동 증가가있는 테이블이없는 경우 문제가 될 수 있습니다.


3

당신은 이것을 시도 할 수 있습니다. 그것은 나를 위해 잘 작동합니다.

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;

2

information_schema 데이터베이스를 사용하는 경우이 mysql 코드를 사용할 수 있습니다 (여기서 쿼리에서 행에 대해 널값이있는 테이블을 표시하지 않는 위치).

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

1

다음 쿼리는 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);';

1

이것이 실제 수를 얻기 위해 내가하는 일입니다 (스키마를 사용하지 않음)

더 느리지 만 더 정확합니다.

그것은 두 단계 프로세스입니다

  1. DB의 테이블 목록을 가져옵니다. 당신은 그것을 사용하여 얻을 수 있습니다

    mysql -uroot -p mydb -e "show tables"
  2. 이 bash 스크립트에서 배열 변수에 테이블 목록을 작성하고 지정하십시오 (아래 코드와 같이 단일 공백으로 구분됨).

    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

1

또 다른 옵션 : 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 테이블이 많으면 모든 행을 계산하는 데 시간이 더 걸릴 수 있습니다.


0

PHP를 사용하여 TABLES와 ALL RECORDS를 계산하는 방법은 다음과 같습니다.

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

데이터를 무시할 경우 count (*)를 사용하지 않는 이유는 무엇입니까?
Svetoslav Marinov

0

Poster는 계산하지 않고 행 수를 원했지만 어떤 테이블 엔진을 지정하지 않았습니다. InnoDB를 사용하면 한 가지 방법 만 알 수 있습니다.

이것이 내가 감자를 선택하는 방법입니다.

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

테이블 엔진에 관계없이 저장 프로 시저를 설치할 권한이없고 설치 할 필요없이 데이터베이스의 각 테이블에 몇 개의 행이 있는지 알 수있는 것 이외의 다른 주장은 없습니다. 루비 또는 PHP. 예, 녹슬어요 그렇습니다. count (*)가 정확합니다.


0

위의 @Nathan의 대답을 기반으로하지만 "최종 조합 제거"및 출력 정렬 옵션없이 다음 SQL을 사용합니다. 다른 SQL 문을 생성 한 다음 실행합니다.

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 

충분히 큰 group_concat_max_len서버 변수 값이 필요 하지만 MariaDb 10.2.4부터 기본값은 1M입니다.


0

아래 코드는 모든 이야기에 대한 선택 쿼리를 생성합니다. 마지막 "UNION ALL"을 삭제하고 모든 결과를 선택하고 실행할 새 쿼리 창을 붙여 넣으십시오.

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'

-1

정확한 숫자를 원하면 다음 루비 스크립트를 사용하십시오. Ruby와 RubyGems가 필요합니다.

다음 보석을 설치하십시오 :

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

-4

테이블 수와 이름을 알고 각각 기본 키가 있다고 가정하면 교차 조인을 함께 사용 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 Fiddle 예제입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.