pokaż nazwę tabeli + liczbę rekordów dla każdej tabeli w bazie danych mysql innodb

10

Jak wyświetlić wszystkie tabele w bieżącej bazie danych wraz z liczbą wierszy tabeli.

Innymi słowy, czy możesz pomyśleć o zapytaniu, które mogłoby wymyślić coś takiego w mysql?

+------------------------++------------------------+
| Tables_in_database     |  Number of rows         |
+------------------------++------------------------+
| database 1             |   1000                  |
| database 2             |   1500                  |
+------------------------++------------------------+

Mile widziane są różne podejścia.

sjdh
źródło
Czy używasz MyISAM lub InnoDB? Czy spojrzałeś na to pytanie ?
Aaron Bertrand
@AaronBertrand Dzięki, to pytanie jest ciekawe. Używam innodb
sjdh

Odpowiedzi:

8

Mam bardzo agresywne podejście, używając dynamicznego SQL Brute Force

SET group_concat_max_len = 1024 * 1024 * 100;
SELECT CONCAT('SELECT * FROM (',GROUP_CONCAT(CONCAT('SELECT ',QUOTE(tb),' Tables_in_database,
COUNT(1) "Number of Rows" FROM ',db,'.',tb) SEPARATOR ' UNION '),') A;')
INTO @sql FROM (SELECT table_schema db,table_name tb
FROM information_schema.tables WHERE table_schema = DATABASE()) A;
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;

Przykład: dostaję to w mojej testowej bazie danych

mysql> use test
Database changed
mysql> SET group_concat_max_len = 1024 * 1024 * 100;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT CONCAT('SELECT * FROM (',GROUP_CONCAT(CONCAT('SELECT ',QUOTE(tb),' Tables_in_database,
    '> COUNT(1) "Number of Rows" FROM ',db,'.',tb) SEPARATOR ' UNION '),') A;')
    -> INTO @sql FROM (SELECT table_schema db,table_name tb
    -> FROM information_schema.tables WHERE table_schema = DATABASE()) A;
Query OK, 1 row affected (0.00 sec)

mysql> PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

+--------------------+----------------+
| Tables_in_database | Number of Rows |
+--------------------+----------------+
| biblio             |              3 |
| biblio_old         |              7 |
| dep                |              5 |
| e                  |             14 |
| emp                |              4 |
| fruit              |             12 |
| fruit_outoforder   |             12 |
| nums_composite     |              0 |
| nuoji              |              4 |
| prod               |              3 |
| prodcat            |              6 |
| test2              |              9 |
| worktable          |              5 |
| yoshi_scores       |             24 |
+--------------------+----------------+
14 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql>

SPRÓBUJ !!!

CAVEAT: Jeśli wszystkie tabele są MyISAM, stanie się to bardzo szybko. Jeśli wszystkie tabele są InnoDB, każda tabela zostanie policzona. Może to być brutalne i nieubłagane w przypadku bardzo dużych tabel InnoDB.

RolandoMySQLDBA
źródło
To świetny przykład dynamicznego SQL. Dzięki!
sjdh
Starałem się zastąpić FROM information_schema.tablesprzez FROM show tables. Czy możesz wyjaśnić, dlaczego to nie działa?
sjdh
Wow, to jest bardzo przydatne !!
Tommy
Chciałbym zobaczyć wersję, która iteruje we wszystkich bazach danych. Próbowałem uruchomić, SELECT DISTINCT table_schema FROM information_schema.tablesale nie mogłem wymyślić, jak zawinąć zapytanie, aby uruchomić te wyniki. Jeśli kiedykolwiek wymyślę
Ryan
Właściwie stwierdziłem, że już odpowiedziałeś na dba.stackexchange.com/a/102284/18098, ale jest co najmniej jedna literówka. Nawet po naprawieniu „DEALLCOATE” nie mogę uruchomić wersji Wszystkie bazy danych. Nie jestem zaznajomiony zSELECT @CountSQL\G
Ryan
6

Wypróbuj poniższe zapytanie bez zapytania dynamicznego

SELECT Table_name AS TablesInDatabase ,table_rows AS NumberOfRows 
FROM information_schema.tables 
WHERE Table_schema=DATABASE(); 
Pydi Raju
źródło
1
Ta metoda jest niezawodna tylko w przypadku bazy danych MyISAM. InnoDB nie przechowuje liczników wierszy w żadnej części swojej architektury ani w schemacie INFORMACJE_SCHEMA. (Zobacz mój post dba.stackexchange.com/questions/17926/... ). Dynamiczne podejście do INFORMACJE_SCHEMA jest jedynym sposobem dla tabel InnoDB.
RolandoMySQLDBA
Dziękujemy za udostępnienie tej metody. Mogę potwierdzić, że ta metoda daje nieco inne liczby dla niektórych moich tabel. Wszystkie moje tabele są przechowywane w silniku pamięci InnoDB.
sjdh
najlepsza odpowiedź, działa jak urok.
Pablo Pazos,
1

Może to zapytanie może być pomocne. Pokazuje rozmiar danych i liczbę rekordów.

SET @table=(SELECT DATABASE());
select @table;
SELECT 
     table_schema as `Database`, 
     table_name AS `Table`, 
     round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB`,
     table_rows as 'Rows'
FROM information_schema.TABLES 
WHERE table_schema = @table
ORDER BY (data_length + index_length) DESC;
RikW
źródło
1

Uzyskaj dokładne liczby wierszy dla wszystkich tabel w MySQL za pomocą skryptu powłoki.

ustaw parametr w pliku parameter.config jako

# Server Details
host_server=10.109.25.37

# Mysql credentials
mysql_user=root
mysql_pass=root
mysql_port=3306

Skrypt do policzenia to:

#!/bin/bash
# This Script is used to take rows count of mysql all user database

# Read Parameter
source parameter.config

# Find path
MY_PATH="`dirname \"$0\"`"
#echo "$MY_PATH"

start=`date +%s`
echo -e "\n\n"
echo MySQL script start runing at Date and Time is: `date +"%D %T"`
echo -e "@@@ Start of rows Count of MySQL on Old Ficus Release $host_server @@@"

echo -e "\n***** MySQL Rows Count Start *****"

#Make directory to save rows count
NOW="$(date +%Y%m%dT%H%M%S)"
dir_name="mysqlRows_$host_server"
if [ ! -d "$MY_PATH/$dir_name" ]; then
    mkdir "$MY_PATH/$dir_name"
fi
echo -e "\n..... Directory $dir_name is Created for mysql....."

echo -e "\n..... Check MySQL Connection ....."
# Verifying mysql connections on new release machine
MYSQL_CONN="-u$mysql_user -p$mysql_pass -h$host_server"
mysql ${MYSQL_CONN} -e "exit"
if [ $? -eq 0 ];
then
    echo -e "\n..... MySQL Database Connection Successful on server $host_server ....."
else
    echo -e "\n..... MySQL Database Connection Fail. Please verify $host_server credential ....."
    exit
fi

echo -e "\nReading MySQL database names..."
mysql ${MYSQL_CONN} -ANe "SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('mysql','information_schema','performance_schema')" > $MY_PATH/$dir_name/dbs_$NOW.txt
DBS="$(cat $MY_PATH/$dir_name/dbs_$NOW.txt)"
# echo -e "\nList of databases:\t" ${DBS}

echo -e "\n..... Running for row count of tables of all user databases ....."

# All User databases
for db in ${DBS[@]}
do
    # echo $db , ${db[@]} 
    # Find list of database
    echo -e "\n\t... Running for ${db[@]} database tables list ..."
    mysql ${MYSQL_CONN} -ANe "SELECT  TABLE_NAME FROM information_schema.TABLES WHERE  TABLE_SCHEMA IN ('${db[@]}')" > $MY_PATH/$dir_name/${db[@]}_tables_$NOW.txt
    TBL="$(cat $MY_PATH/$dir_name/${db[@]}_tables_$NOW.txt)"
    # echo "Table in $db are:" ${TBL[@]}, $MY_PATH/$dir_name/${db[@]}_tables.txt

    echo -e "\n\t... Running for ${db[@]} database tables rows count ..."
    for tbs in ${TBL[@]}
    do
        # echo $tbs , ${tbs[@]}
        count=$(mysql -u$mysql_user -p$mysql_pass -h$host_server ${db[@]} -N -e "select count(*) from ${tbs[@]}")
        # count="$(cat /tmp/$db_rows_$NOW.txt)"
        # echo "Row in $tb Table of $db database are:" ${count[@]}
        echo -e "${db[@]},${tbs[@]},$count" >> $MY_PATH/$dir_name/${db[@]}_rows_$NOW.csv
        echo -e "${db[@]},${tbs[@]},$count" >> $MY_PATH/$dir_name/alldbs_rows_$NOW.csv
    done
done
echo -e "\n..... End of rows count of tables of all databases ....."

echo -e "\n===== MySQL Rows Count End ====="

# Display script execution time.
echo -e "@@@ Completion of Rows Count of MySQL on old Release $host_server @@@"
echo Script ended at Date and Time is: `date +"%D %T"`
end=`date +%s`
runtime=$((end-start))
echo -e "Time(in second) taken for running MySQL row count script:" $runtime "Sec."

zapisz to w pliku „mysqlrowscount.sh”, uruchom ten skrypt za pomocą polecenia:

bash mysqlrowscount.sh
Sarita
źródło