মাইএসকিউএল ডাটাবেসে SELECT count()
প্রতিটি টেবিলে একটি চালনা না করে সমস্ত সারণিতে সারিগুলির গণনা পাওয়ার কোনও উপায় আছে কি ?
মাইএসকিউএল ডাটাবেসে SELECT count()
প্রতিটি টেবিলে একটি চালনা না করে সমস্ত সারণিতে সারিগুলির গণনা পাওয়ার কোনও উপায় আছে কি ?
উত্তর:
SELECT SUM(TABLE_ROWS)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{your_db}';
যদিও দস্তাবেজগুলি থেকে নোট করুন: InnoDB টেবিলগুলির জন্য, সারি গণনাটি এসকিউএল অপ্টিমাইজেশনে ব্যবহৃত মোটামুটি অনুমান । সঠিক গণনাগুলির জন্য আপনাকে COUNT (*) ব্যবহার করতে হবে (যা আরও ব্যয়বহুল)।
আপনি সম্ভবত টেবিল টেবিলের সাথে কিছু রেখে দিতে পারেন । আমি এটি কখনই করি নি, তবে দেখে মনে হচ্ছে এটির একটি কলাম TABLE_ROWS এর জন্য এবং একটি টেবিল নামের জন্য রয়েছে ।
প্রতি টেবিলে সারি পেতে, আপনি এই জাতীয় একটি কোয়েরি ব্যবহার করতে পারেন:
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '**YOUR SCHEMA**';
@ ভেনক্যাট্রামান এবং অন্যান্যদের মতো আমি INFORMATION_SCHEMA. টেবিলগুলি অবিশ্বাস্য দেখতে পেলাম (ইনোডিবি, মাইএসকিউএল 5.1.44 ব্যবহার করে) প্রতিবার যখন আলাদা করে সারণি এমনকি চালানো টেবিলগুলিতে চালিত করি তখন বিভিন্ন সারি গণনা প্রদান করে। এখানে একটি তুলনামূলকভাবে হ্যাকি (তবে নমনীয় / অভিযোজিত) একটি বড় এসকিউএল বিবৃতি উত্পন্ন করার উপায় যা আপনি রুবি রত্ন এবং স্টাফ ইনস্টল না করে একটি নতুন ক্যোয়ারিতে পেস্ট করতে পারেন।
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 ব্যবহার করছি।
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)
তারপরে আপনি সহজেই পিএইচপি বা সারি গণনার জন্য "সর্বোত্তম অনুমান" দিতে 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% সঠিক। অনুমিত সারিগুলির চেয়ে অনেক ভাল।
এর সৌন্দর্যটি হ'ল পারফরম্যান্সে ফিরে আসা সারি গণনাগুলি আপনার জন্যও মুছে ফেলা হয়েছে, কারণ সবচেয়ে বড় নালার উপর কাজ করে না। যদিও অটো বর্ধনের সাথে আপনার কোনও টেবিল না থাকলে এটি একটি সমস্যা হতে পারে।
আপনি এটি চেষ্টা করতে পারেন। এটা আমার জন্য ভাল কাজ করছে।
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;
আপনি যদি তথ্য_সেমি ডাটাবেস ব্যবহার করেন তবে আপনি এই মাইএসকিএল কোডটি ব্যবহার করতে পারেন (যেখানে অংশটি সন্ধানগুলির সারণীর জন্য নাল মান রাখার সারণীগুলি প্রদর্শন করে না):
SELECT TABLE_NAME, TABLE_ROWS
FROM `TABLES`
WHERE `TABLE_ROWS` >=0
নিম্নলিখিত কোয়েরিতে একটি (নোটার) ক্যোয়ারী তৈরি করা হয়েছে যা প্রতিটি স্কিমা থেকে তথ্য_সেমিমা. টেবিলগুলিতে তালিকাভুক্ত প্রতিটি টেবিলের জন্য গণনা (*) এর মান পাবে। এখানে দেখানো ক্যোয়ারির সম্পূর্ণ ফলাফল - সমস্ত সারি এক সাথে নেওয়া - একটি বৈধ এসকিউএল বিবৃতি অর্ধকোলনে শেষ হওয়া - কোনও জড়ান 'ইউনিয়ন' নিয়ে গঠিত। ডাংলিং ইউনিয়ন নীচের প্রশ্নের মধ্যে একটি ইউনিয়ন ব্যবহার এড়ানো হয়।
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
আরও একটি বিকল্প: ইনোএনডিবি-র জন্য এটি তথ্য_সেমিমা থেকে ডেটা ব্যবহার করে T টেবিলগুলি (এটি দ্রুত হিসাবে) ইনোডিবি - সঠিক গণনা পেতে গণনা (*) নির্বাচন করুন। এছাড়াও এটি মতামত উপেক্ষা করে।
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 টেবিল থাকে সমস্ত সারি গণনা করতে আরও সময় নিতে পারে।
এইভাবে আমি পিএইচপি ব্যবহার করে টেবিলগুলি এবং সমস্ত রেকর্ডগুলি গণনা করি:
$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"
}
আমি এটি ব্যতীত অন্য কোন বিষয়ে জোর দিচ্ছি না যে এটি টেবিল ইঞ্জিন নির্বিশেষে এবং সঞ্চিত পদ্ধতি ইনস্টল করার অনুমতি না নিয়ে এবং ইনস্টল করার প্রয়োজন ছাড়াই ডাটাবেজে প্রতিটি সারণীতে কত সারি রয়েছে তা পাওয়া সত্যিই কুৎসিত কিন্তু কার্যকর উপায় and রুবি বা পিএইচপি। হ্যাঁ, এটি মরিচা হ্যাঁ তা গণনা করা। গণনা (*) সঠিক।
উপরে @ নাথান এর উত্তরের উপর ভিত্তি করে, তবে "চূড়ান্ত ইউনিয়ন অপসারণ" এবং আউটপুটটি বাছাইয়ের বিকল্পের সাথে আমি নীচের এসকিউএল ব্যবহার করি। এটি অন্য এসকিউএল বিবৃতি উত্পন্ন করে যা কেবলমাত্র চালানো হয়:
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 থেকে এটি ডিফল্ট 1 এম হতে হবে।
নীচের কোডটি সমস্ত গল্পের জন্য নির্বাচিত ক্যোয়ারী তৈরি করে। কেবল সর্বশেষ "ইউনিয়ন সমস্ত" মুছুন সমস্ত ফলাফল নির্বাচন করুন এবং চালানোর জন্য একটি নতুন ক্যোয়ারী উইন্ডোটি পেস্ট করুন।
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;
এখানে একটি এসকিউএল ফিডল উদাহরণ রয়েছে।