क्या SELECT count()
प्रत्येक मेज पर चलने के बिना MySQL डेटाबेस में सभी तालिकाओं में पंक्तियों की गिनती प्राप्त करने का एक तरीका है ?
क्या SELECT count()
प्रत्येक मेज पर चलने के बिना MySQL डेटाबेस में सभी तालिकाओं में पंक्तियों की गिनती प्राप्त करने का एक तरीका है ?
जवाबों:
SELECT SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{your_db}';
यद्यपि डॉक्स से ध्यान दें: InnoDB तालिकाओं के लिए, पंक्ति गणना केवल SQL ऑप्टिमाइज़ेशन में उपयोग किया जाने वाला एक मोटा अनुमान है। आपको सटीक गणना (जो अधिक महंगी है) के लिए COUNT (*) का उपयोग करना होगा।
आप शायद टेबल के साथ कुछ डाल सकते हैं । मैंने इसे कभी नहीं किया है, लेकिन ऐसा लगता है कि इसमें TABLE_ROWS के लिए एक कॉलम है और एक TABLE NAME के लिए है ।
प्रति तालिका पंक्तियाँ प्राप्त करने के लिए, आप इस तरह से एक क्वेरी का उपयोग कर सकते हैं:
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '**YOUR SCHEMA**';
@Venkatramanan और अन्य लोगों की तरह मैंने INFORMATION_SCHEMA.TABLES को अविश्वसनीय पाया (InnoDB, MySQL 5.1.44 का उपयोग करके), हर बार अलग-अलग पंक्ति गिनाते हुए मैंने इसे क्विज़ टेबल पर भी चलाया। यहाँ एक अपेक्षाकृत हैकसी (लेकिन लचीला / अनुकूलनीय) तरीका है एक बड़ा 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
अच्छा उत्पादन प्राप्त करने के लिए पिछले संघ को छोड़कर कॉपी और पेस्ट करें,
+------------------+-----------------+
| 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)
मैं बस चलाता हूं:
show table status;
यह आपको हर तालिका के लिए पंक्ति गणना देगा और अन्य जानकारी का एक गुच्छा देगा। मैं ऊपर दिए गए चयनित उत्तर का उपयोग करता था, लेकिन यह बहुत आसान है।
मुझे यकीन नहीं है कि यह सभी संस्करणों के साथ काम करता है, लेकिन मैं 5.5 का उपयोग कर रहा हूं InnoDB इंजन।
SELECT TABLE_NAME,SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_db'
GROUP BY TABLE_NAME;
बस इतना ही चाहिए।
mysql> SELECT TABLE_NAME,SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ngramsdb' GROUP BY TABLE_NAME;
यह संग्रहीत कार्यविधि तालिका को सूचीबद्ध करती है, रिकॉर्ड की गणना करती है, और अंत में रिकॉर्ड की कुल संख्या का उत्पादन करती है।
इस प्रक्रिया को जोड़ने के बाद इसे चलाने के लिए:
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
सरल तरीका:
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 |
+----------------+-----------------+
इस अनुमान समस्या के लिए हैक / वर्कअराउंड का एक सा है।
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 * (टेबल काउंट) पंक्तियों से दूर रहेगा, लेकिन यहां तक कि 4,000 टेबल और 3 मिलियन पंक्तियों के साथ, यह 99.9% सटीक है। अनुमानित पंक्तियों की तुलना में बहुत बेहतर है।
इसका सौंदर्य यह है कि प्रदर्शन में लौटी हुई पंक्ति की गणना आपके लिए, साथ ही मिटा दी जाती है, क्योंकि सबसे बड़ी अशक्तता पर काम नहीं होता है। यह एक मुद्दा हो सकता है अगर आपके पास ऑटो वेतन वृद्धि के साथ कोई तालिका नहीं है, हालांकि।
आप यह कोशिश कर सकते हैं। यह मेरे लिए ठीक काम कर रहा है।
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 कोड का उपयोग कर सकते हैं (जहाँ भाग उन क्वेरी को नहीं दिखाता है जिनमें पंक्तियों के लिए एक शून्य मान है):
SELECT TABLE_NAME, TABLE_ROWS
FROM `TABLES`
WHERE `TABLE_ROWS` >=0
निम्न क्वेरी एक (nother) क्वेरी का उत्पादन करती है, जो सूचना में सूचीबद्ध प्रत्येक स्कीमा से प्रत्येक तालिका के लिए गणना (*) का मान प्राप्त करेगी। यहां दिखाए गए क्वेरी का संपूर्ण परिणाम - सभी पंक्तियों को एक साथ लिया गया - जिसमें एक अर्धवृत्त समाप्त होने वाला एक वैध एसक्यूएल विवरण शामिल है - कोई झूलने वाला 'संघ' नहीं। नीचे दिए क्वेरी में संघ के उपयोग से लटकती यूनियन से बचा जाता है।
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);';
यह वह है जो मैं वास्तविक गणना प्राप्त करने के लिए करता हूं (स्कीमा का उपयोग नहीं)
यह धीमा है लेकिन अधिक सटीक है।
यह दो चरणों वाली प्रक्रिया है
अपने डीबी के लिए तालिकाओं की सूची प्राप्त करें। आप इसका उपयोग करके प्राप्त कर सकते हैं
mysql -uroot -p mydb -e "show tables"
इस बैश स्क्रिप्ट में सारणी चर के लिए तालिकाओं की सूची बनाएं और असाइन करें (नीचे दिए गए कोड की तरह एकल स्थान द्वारा अलग)
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 के लिए, यह जानकारी_schema.TABLES से डेटा का उपयोग करता है (जैसा कि यह तेज़ है), InnoDB के लिए - सटीक गिनती प्राप्त करने के लिए गिनती (*) का चयन करें। इसके अलावा यह विचारों की अनदेखी करता है।
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 टेबल हैं, तो सभी पंक्तियों को गिनने में अधिक समय लग सकता है।
यह है कि मैं 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.";
पोस्टर बिना गिनती के पंक्ति गणना चाहता था, लेकिन यह निर्दिष्ट नहीं करता था कि कौन सा टेबल इंजन है। 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। हाँ, इसकी जंग। हाँ, यह मायने रखता है। गिनती (*) सटीक है।
ऊपर दिए गए @ नाथन के उत्तर के आधार पर, लेकिन "अंतिम यूनियन को हटाने" की आवश्यकता के बिना और आउटपुट को सॉर्ट करने के विकल्प के साथ, मैं निम्नलिखित एसक्यूएल का उपयोग करता हूं। यह एक और 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
सर्वर वैरिएबल के पर्याप्त बड़े मूल्य की आवश्यकता होती है लेकिन मारियाडब 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'
यदि आप सटीक संख्याएँ चाहते हैं, तो निम्न रूबी लिपि का उपयोग करें। आपको रूबी और रूबीजम्स की आवश्यकता है।
निम्नलिखित रत्न स्थापित करें:
$> 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.
यदि आप तालिकाओं और उनके नामों की संख्या जानते हैं, और यह मानते हुए कि उनमें से प्रत्येक के पास प्राथमिक कुंजी है, तो आप 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 उदाहरण है।