





С Таблицы стол, наверное, можно что-нибудь скомпоновать. Я никогда этого не делал, но похоже, что в нем есть столбец для TABLE_ROWS и один для НАЗВАНИЕ ТАБЛИЦЫ.
Чтобы получить строки в таблице, вы можете использовать такой запрос:
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '**YOUR SCHEMA**';
Есть ли другой способ получить table_row и table_name? Потому что мне нужен точный результат, а не приблизительная оценка. Спасибо.
как упоминал Куранл, это возвращает только оценку и, вероятно, вернет разные результаты при запуске несколько раз
Таблицы с как минимум ~ 250 записями, кажется, сообщают о разном количестве строк каждый раз, когда я запускаю этот запрос.
Ой ... Хотел бы я видеть слово "Оценка" перед рукой ... как вчера! Не следует ли отказываться от ответа? Поскольку ОП не просил «оценку», и кажется глупым думать, что ему может понадобиться оценка. "оценка" Могла бы спасти маронов вроде меня от пропуска "оценки"?
SELECT SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{your_db}';
Примечание из документов: Для таблиц InnoDB, количество строк - это только приблизительная оценка используется при оптимизации SQL. Вам нужно будет использовать COUNT (*) для точного подсчета (что дороже).
или, если вы хотите для каждой таблицы: SELECT table_name, TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}';
Есть ли другой способ получить table_row и table_name? Потому что мне нужен точный результат, а не приблизительная оценка. Спасибо.
@krunalshah, это одно из ограничений InnoDB. См. dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html, раздел Ограничения для таблиц InnoDB, для получения дополнительной информации. Вы всегда можете использовать SELECT COUNT (*) FROM t, что, однако, намного медленнее
@Marking Я почти уверен, что SELECT COUNT(*) ... все еще подлежит подсчету
Джайцу, нет, это не так. count (*) (или более реалистично count (id)) - это то, что mysql использует для подсчета строк, не так ли? В любом случае, я просто протестировал его и получил большее число для вызова count (), чего бы оно ни стоило.
SELECT TABLE_NAME, SUM (TABLE_ROWS) N FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}' group by TABLE_NAME;
Где именно "COUNT (*)" соответствует приведенному выше ответу? Хотелось бы точного результата.
Почему в моем случае TABLE_ROWS несовместима для каждого запроса? Я использую mariadb 10
Эта хранимая процедура составляет список таблиц, подсчитывает записи и в конце выдает общее количество записей.
Чтобы запустить его после добавления этой процедуры:
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
Если вы используете базу данных information_schema, вы можете использовать этот код mysql (часть where заставляет запрос не отображать таблицы с нулевым значением для строк):
SELECT TABLE_NAME, TABLE_ROWS
FROM `TABLES`
WHERE `TABLE_ROWS` >=0
Если вам нужны точные числа, используйте следующий скрипт ruby. Вам нужны 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.
Как и @Venkatramanan и другие, я нашел INFORMATION_SCHEMA.TABLES ненадежным (с использованием InnoDB, MySQL 5.1.44), давая разное количество строк каждый раз, когда я запускаю его, даже в стабилизированных таблицах. Вот относительно хитрый (но гибкий / адаптируемый) способ создания большого SQL-оператора, который вы можете вставить в новый запрос, без установки драгоценных камней Ruby и прочего.
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)
Спасибо, я надеялся, что мне не придется устанавливать какие-либо плагины / драгоценные камни, чтобы получить точные подсчеты.
Слишком долго выполняется в случае большого количества таблиц в базе данных.
добавить "select * from (" в начале и ") в качестве порядка вывода по точному_строку_count desc" в конце сгенерированного запроса после удаления последнего UNION, чтобы получить порядок по количеству таблиц по убыванию
Чтобы исключить представления: WHERE table_schema = 'my_schema' и TABLE_TYPE LIKE '% TABLE%'
Это НАСТОЯЩИЙ ответ для меня.
Вот как я считаю ТАБЛИЦЫ и ВСЕ ЗАПИСИ с помощью PHP:
$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 (*), если вы будете игнорировать данные?
SELECT TABLE_NAME,SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_db'
GROUP BY TABLE_NAME;
Это все, что вам нужно.
производит оценочные строки таблицы - сравните с "mysql_num_rows ($ tableresult)"
это лучший ответ на самом деле! Также проще выполнить из mysql cli: mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
Следующий запрос создает (другой) запрос, который получит значение count (*) для каждой таблицы из каждой схемы, перечисленной в information_schema.tables. Весь результат запроса, показанный здесь - все строки вместе взятые - представляет собой действительный оператор 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);';
Я просто бегу:
show table status;
Это даст вам количество строк для КАЖДОЙ таблицы плюс кучу другой информации. Раньше я использовал выбранный выше ответ, но это намного проще.
Я не уверен, работает ли это со всеми версиями, но я использую 5.5 с движком InnoDB.
К сожалению, если вы используете InnoDB, этот подход страдает теми же неточностями, что и другие методы, описанные выше. Например, у меня есть таблица InnoDB, содержащая примерно 65 000 строк, но эти методы сообщают, что в ней содержится от 350 000 до более 780 000 строк.
Для БД с несколькими строками это довольно точно (или, достаточно точно для моих нужд). Он дал мне 1086 строк для таблицы, в которой COUNT (*) сообщил о 904 строках.
Однозначно лучший ответ. Я использую InnoDB, но мне нужна только быстрая команда, чтобы узнать порядок величины.
Серьезно, хотелось бы, чтобы это было принято. Не использую InnoDB и дает мне точный ответ.
Это берет столбец TABLE_ROWS из таблицы INFORMATION_SCHEMA.TABLES. Обратите внимание, что эта информация (предоставленная show table status или столбцом TABLE_ROWS) является лишь приблизительной оценкой, которая может быть неточной для InnoDB (я еще не тестировал MyISAM).
Количество строк не является точным, но «Auto_increment» может дать вам точное количество, если вы не удалили ни одной строки из таких таблиц.
Вы можете попробовать это. У меня все работает нормально.
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;
Это то, что я делаю, чтобы получить фактическое количество (без использования схемы)
Это медленнее, но точнее.
Это двухэтапный процесс на
Получите список таблиц для вашей БД. Вы можете получить это, используя
mysql -uroot -p mydb -e "show tables"
Создайте и назначьте список таблиц переменной массива в этом сценарии bash (разделенных одним пробелом, как в приведенном ниже коде)
array=( table1 table2 table3 )
for i in "${array[@]}"
do
echo $i
mysql -uroot mydb -e "select count(*) from $i"
done
Запустить его:
chmod +x script.sh; ./script.sh
Плакат требовал подсчета строк без подсчета, но не указывал, какой движок таблицы. С 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 (*) является точным.
Если вы знаете количество таблиц и их имена и предполагаете, что каждая из них имеет первичные ключи, вы можете использовать перекрестное соединение в сочетании с 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.
Еще один вариант: для не 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, подсчет всех строк может занять больше времени.
Я добавил строку с SELECT CONCAT(@selects, ' ORDER BY TABLE_ROWS ') INTO @selects; перед PREPARE, чтобы получить более читаемый результат, но это лучший ответ для меня.
Есть небольшое решение этой проблемы с оценкой.
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 или что-то еще, чтобы вернуть максимум из двух столбцов данных, чтобы дать «наилучшую оценку» количества строк.
т.е.
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 * (количество таблиц) строк, но даже с 4000 таблиц и 3 миллиона строк это 99,9% точности. Намного лучше, чем предполагаемые строки.
Прелесть этого заключается в том, что счетчики строк, возвращаемые в performance_schema, также стираются для вас, потому что величайший не работает с нулевыми значениями. Однако это может быть проблемой, если у вас нет таблиц с автоматическим приращением.
Простой способ:
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 |
+----------------+-----------------+
Основываясь на ответе @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.
Приведенный ниже код генерирует запрос выбора для всех сказок. Просто удалите последний "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'
Расширенный ответ, который также подходит для InnoDB: stackoverflow.com/questions/24707814/…