খুব বড় টেবিলের সারিগুলির সঠিক সংখ্যা গণনা করার দ্রুততম উপায়?


234

আমি নিবন্ধগুলি জুড়ে এসেছি যা উল্লেখ করে যে SELECT COUNT(*) FROM TABLE_NAMEটেবিলে প্রচুর সারি এবং প্রচুর কলাম রয়েছে তখন ধীর হয়ে যাবে।

আমার কাছে একটি টেবিল রয়েছে যাতে বিলিয়নেরও সারি থাকতে পারে [এতে প্রায় 15 টি কলাম রয়েছে]। কোনও সারণির সারি সংখ্যার নির্ভুল গণনা পাওয়ার আরও ভাল উপায় কি ?

আপনার উত্তরের আগে দয়া করে নিম্নলিখিতটি বিবেচনা করুন:

  • আমি একটি ডাটাবেস বিক্রেতার স্বাধীন সমাধান খুঁজছি। এটি মাইএসকিউএল , ওরাকল , এমএস এসকিউএল সার্ভারকে অন্তর্ভুক্ত করা হলে এটি ঠিক আছে । তবে যদি সত্যিই কোনও ডাটাবেস বিক্রেতার স্বাধীন সমাধান না থাকে তবে আমি বিভিন্ন ডাটাবেস বিক্রেতাদের জন্য বিভিন্ন সমাধানের জন্য স্থির করব।

  • এটি করার জন্য আমি অন্য কোনও বাহ্যিক সরঞ্জাম ব্যবহার করতে পারি না। আমি মূলত একটি এসকিউএল ভিত্তিক সমাধান খুঁজছি।

  • আমি আর আমার ডেটাবেস ডিজাইনকে সাধারণ করতে পারি না। এটি ইতিমধ্যে 3NF- এ রয়েছে এবং এরপরে এর চারপাশে প্রচুর কোড ইতিমধ্যে লেখা হয়েছে।


4
আর মাত্র কৌতূহল হ'ল আপনার যখন
কয়েকশো

2
আমরা কি সবাই আশা করব না যে এই বিশেষ নির্মাণটি আমাদের ডাটাবেস বিক্রেতার দ্বারা অনুকূলিত হয়েছে?
কেভিনডিটাইম

5
@ স্বরঙ্গ, এই ডাটাবেস রক্ষণাবেক্ষণের উদ্দেশ্যটি কি সারণীতে সারিগুলির সঠিক সংখ্যাটি অবশ্যই জানতে হবে সে সম্পর্কে আপনি কি আরও কিছু ব্যাখ্যা করতে পারেন ? আমি ভাবতে পারি না। এবং কেভিন বলেছেন যে, যদি COUNT (*) এর চেয়ে আরও দ্রুততর উপায় থাকে তবে ডিবিএমএস বিক্রেতা অবশ্যই এটি ব্যবহারের জন্য COUNT (*) পুনরায় প্রয়োগ করতে হবে ...
টনি অ্যান্ড্রুজ

3
অবশ্যই যদি টেবিলটি প্রায়শই লিখিত হয়ে থাকে তবে আপনার সঠিক গণনাটি নির্দিষ্ট সময়ে কেবলমাত্র নির্দিষ্ট পয়েন্টের জন্য সঠিক হবে এবং যদি আপনি কোয়েরিতে কোনও টেবিল লক না রেখে অন্য প্রক্রিয়াগুলি টেবিলে লিখিত হয় তবে তা সঠিকও নাও হতে পারে।
স্টিভ ফোর্ড

2
আপনি একটি ঘূর্ণায়মান গণনা রাখতে ট্রিগারগুলি সন্নিবেশ এবং মুছতে ব্যবহার করতে পারেন?
পেপারাজ্জো

উত্তর:


246

সহজ উত্তর:

  • ডাটাবেস বিক্রেতার স্বাধীন সমাধান = মান ব্যবহার করুন = COUNT(*)
  • আছে আনুমানিক SQL সার্ভার সমাধান কিন্তু COUNT টি (*) ব্যবহার করবেন না সাধ্যের বাইরে =

মন্তব্য:

COUNT (1) = COUNT (*) = COUNT (প্রাথমিককি) কেবলমাত্র ক্ষেত্রে

সম্পাদনা:

এসকিউএল সার্ভার উদাহরণ (1.4 বিলিয়ন সারি, 12 কলাম)

SELECT COUNT(*) FROM MyBigtable WITH (NOLOCK)
-- NOLOCK here is for me only to let me test for this answer: no more, no less

1 রান, 5:46 মিনিট, গণনা = 1,401,659,700

--Note, sp_spaceused uses this DMV
SELECT
   Total_Rows= SUM(st.row_count)
FROM
   sys.dm_db_partition_stats st
WHERE
    object_name(object_id) = 'MyBigtable' AND (index_id < 2)

2 রান, উভয়ই 1 সেকেন্ডের নিচে, গণনা = 1,401,659,670

দ্বিতীয়টির কম সারি রয়েছে = ভুল। লেখার উপর নির্ভর করে একই বা আরও কিছু হবে (মুছে ফেলাগুলি এখানে কয়েক ঘণ্টার মধ্যে শেষ হয়ে যায়)


9
নাহ COUNT(*) = COUNT(key),। এটা ঠিক ভুল। যদি কোনও NOT NULLপ্রতিবন্ধকতা না থাকে - তবে তারা সমান হতে পারে না (ফলাফলের পাশাপাশি কার্যকর করার পরিকল্পনায়)।
zerkms

14
@ জারকামসবি: COUNT (কী) এর জন্য আমি বলতে চাইছি COUNT (প্রাথমিককি) যা অযোগ্য হওয়া উচিত। আমি স্পষ্ট করব
gbn

8
(NOLOCK) এমন কোনও জিনিস নয় যা এটিকে উত্পাদনে চালিত করতে দেয় এবং এটি একটি ভুল গণনা হতে পারে। আপনি যখন সেই ইঙ্গিতটি ব্যবহার করেন, অবশ্যই তা লকগুলি প্রতিরোধ করে তবে একটি উত্পাদনের বাক্সের পার্শ্ব প্রতিক্রিয়া হ'ল আপনি কিছু পরিস্থিতিতে সারিগুলি দুবার গণনা করতে পারেন বা অন্যান্য পরিস্থিতিতে সারিগুলি এড়িয়ে যেতে পারেন। NOLOCK এমন কোনও টেবিলের উপরে ব্যবহার করা ভাল যা এতে লেখা হচ্ছে না কারণ এটি "নোংরা পাঠ্য" কে মঞ্জুরি দেয়। লোকেরা এই ইঙ্গিতটি ব্যবহার করার পরামর্শ দিবেন না যতক্ষণ না তারা পরিণতিগুলি সম্পূর্ণরূপে বুঝতে পারে
দাভোস

4
@ মিশ্রসুদ একমাত্র সঠিক ক্যোয়ারী নির্বাচন করুন নির্বাচন করুন (*) তবে এটি ধীর গতির। আপনি হয় সঠিক এবং ধীর, বা রুক্ষ এবং দ্রুত করতে পারেন। আপনি যা করেন তার উপর নির্ভর করবে আপনার প্রয়োজনের জন্য গণনাটি কী প্রয়োজন for কোনও লককে মধ্য লেনদেনের যে সারিগুলি অন্তর্ভুক্ত বা প্রকৃতপক্ষে বা যে কোনও কারণে চলন্ত পৃষ্ঠাগুলি অন্তর্ভুক্ত করতে পারে না।
দাভোস

5
@ জিবিএন খুব সুন্দর সমাধান, আপনি কি বলতে পারবেন কি ব্যবহার index_id < 2?
কমিট

29

মাইএসকিউএল-এ এখন পর্যন্ত সবচেয়ে দ্রুততম উপায় হ'ল:

SHOW TABLE STATUS;

আপনি চাইলে আপনার সমস্ত টেবিলগুলি তত্ক্ষণাত সারি গণনা (যা মোট) আপনার সাথে চাইলে প্রচুর অতিরিক্ত তথ্য পাবেন get


1
স্মার্ট উপায়..এর সাহায্যে আপনি 1 টি ক্যোয়ারিতে একাধিক টেবিলের সারি গণনা পেতে পারেন।
দেওয়াল খান্দেলওয়াল

আপনি কি @gbn এর মতো ~ বিলিয়ন এন্ট্রি সহ টেবিলযুক্ত ডিবিতে চালিয়েছেন এবং সময়টি লক্ষ্য করেছেন?
কেএনইউ

ডাটাবেসের সমস্ত টেবিলের জন্য মোট সারি গণনাটি কোন মান? এবং এগুলি আনুমানিক - আপনি যদি সঠিক সারি গণনা মান চান?
ক্রিভার্প

2
এটি মোটেও কাজ করে না, উদাহরণস্বরূপ, INNODB- এ স্টোরেজ ইঞ্জিন কয়েকটি সারি এবং সারিগুলির সংখ্যা অনুমান করার জন্য এক্সট্রাপোলেটগুলি পড়ে
মার্টিজান শেফার

10

আমি নিবন্ধগুলি জুড়ে এসেছি যে টেবিলটিতে প্রচুর সারি এবং প্রচুর কলাম রয়েছে তখন সারণী COUNT (*) থেকে TABLE_NAME ধীর হয়ে যাবে।

এটি ডাটাবেসের উপর নির্ভর করে। কিছু গতি বাড়িয়ে তোলে, উদাহরণস্বরূপ, সূচীতে সারিগুলি সজীব বা মৃত কিনা তা অনুসরণ করে, কেবল কোনও সূচকে সারিগুলির সংখ্যা বের করতে স্ক্যান করে allowing অন্যেরা তা করে না এবং ফলস্বরূপ পুরো টেবিলটি পরিদর্শন করা এবং একে একে লাইভ সারি গণনা করা প্রয়োজন। হয় বিশাল টেবিলের জন্য ধীর হয়ে যাবে।

নোট করুন যে আপনি সাধারণত ক্যোয়ারী অপ্টিমাইজেশন সরঞ্জাম, টেবিলের পরিসংখ্যান ইত্যাদি ব্যবহার করে একটি ভাল অনুমান বের করতে পারেন, উদাহরণস্বরূপ, আপনি আউটপুটকে বিশ্লেষণ করতে পারবেন explain count(*) from yourtableএবং সারিগুলির সংখ্যার পক্ষে যুক্তিসঙ্গতভাবে ভাল অনুমান করতে পারবেন। যা আমাকে আপনার দ্বিতীয় প্রশ্নে নিয়ে আসে।

আমার কাছে একটি টেবিল রয়েছে যাতে বিলিয়নেরও সারি থাকতে পারে [এতে প্রায় 15 টি কলাম রয়েছে]। কোনও সারণির সারি সংখ্যার নির্ভুল গণনা পাওয়ার আরও ভাল উপায় কি?

সিরিয়াসলি? :-) আপনি কয়েক মিলিয়ন সারি সহ কোনও টেবিল থেকে সঠিক গণনাটি বোঝাতে চান ? তুমি কি সত্যি নিশ্চিত? :-)

আপনি যদি সত্যিই এটি করেন তবে আপনি মোট ট্রিগার ব্যবহার করে তার সন্ধান করতে পারবেন, তবে আপনি যদি তা করেন তবে সম্মতি এবং ডেডলকগুলি বিবেচনা করুন।


হ্যাঁ ডেনিস, সঠিক গণনা প্রয়োজন। :(
স্বরাঙ্গা সরমা

5
এটি একটি ভাগ্যবান যে Google ম্যানেজাররা আপনার বসের চেয়ে আরও যুক্তিসঙ্গত ... ছবিটি যদি অনুমানের সংখ্যার সাথে যুক্ত না হয়ে আপনার প্রতিটি প্রশ্নের জন্য অনুসন্ধানের ফলাফলের সঠিক সংখ্যাটি ফিরিয়ে দেয় তবে তা কত ধীরে ধীরে হবে তা চিত্র।
ডেনিস ডি বার্নার্ডি

অন্তত আপনি আমার সাথে সহানুভূতিশীল। একমাত্র ওরাকল সমাধান সম্পর্কে কীভাবে? এটি আমার সমস্যাটিকে কিছুটা কমিয়ে দেবে। বর্তমানে গ্রাহক ওরাকল ব্যবহার করছেন; সুতরাং আমি যদি কেবল ওরাকলকে নিয়ে কাজ করেই চলে যাই তবে তা [আপাতত] করবে। :)
স্বরঙ্গ সরমা

6
"হ্যাঁ ডেনিস, সঠিক গণনাটি প্রয়োজন: :(" - আমি কেবল অনুমান করতে পারি the এ এবং সারণি বিতে সারিগুলি আপডেট করুন ...? নাকি এটি এর চেয়ে ক্রেজি? ?
টনি অ্যান্ড্রুজ

1
লেনদেন 1 এর আগে 1 টি লেনদেনের আগে লেনদেন শুরু হবে না। "গণনা সারণী" আপডেট ছাড়া অনেকগুলি আপডেটের লেনদেন সমান্তরালে চলতে পারে। "গণনা সারণী" দিয়ে, প্রতিটি লেনদেনের জন্য তার গণনা আপডেট করার জন্য "টিকিট অর্জন করতে হবে"। সুতরাং লেনদেনগুলি টিকিট মেশিনে সারি বেঁধে ফেলা শুরু করে (সূচি নির্ধারণ করে যে কে গণনার টেবিলে লক পেতে পরবর্তী হবে)।
এরউইন স্মাউট

10

কোনও সারণির সারি সংখ্যার নির্ভুল গণনা পাওয়ার আরও ভাল উপায় কি?

আপনার প্রশ্নের সহজ উত্তর দিতে, না

এটি করার জন্য যদি আপনার কোনও ডিবিএমএস স্বতন্ত্র উপায়ের প্রয়োজন হয় তবে দ্রুততম উপায়টি সর্বদা:

SELECT COUNT(*) FROM TableName

কিছু ডিবিএমএস বিক্রেতাদের কাছে দ্রুত উপায় থাকতে পারে যা কেবলমাত্র তাদের সিস্টেমে কাজ করবে। এর মধ্যে কয়েকটি বিকল্প ইতিমধ্যে অন্যান্য উত্তরে পোস্ট করা হয়েছে।

COUNT(*) যাইহোক DBMS (কমপক্ষে কোনও প্রোডির যোগ্য ডিবি) দ্বারা অনুকূলিত হওয়া উচিত, সুতরাং তাদের অপ্টিমাইজেশনকে বাইপাস করার চেষ্টা করবেন না।

পাশের নোটে:
আমি নিশ্চিত যে আপনার টেবিলের আকারের কারণে আপনার অন্যান্য প্রশ্নের অনেকগুলিও শেষ করতে দীর্ঘ সময় নেয়। গতির কথা বিবেচনা করে আপনার স্কিমা ডিজাইনের কথা চিন্তা করে কোনও পারফরম্যান্সের উদ্বেগের সমাধান করা উচিত। আমি বুঝতে পেরেছি যে আপনি বলেছিলেন যে এটি কোনও পরিবর্তন করার বিকল্প নয় তবে এটি হতে পারে যে 10+ মিনিটের প্রশ্নের কোনও বিকল্প নয়। 3 য় এন এফ যখন আপনি গতি প্রয়োজন, এবং কখনও কখনও তথ্য বিভিন্ন সারণিতে বিভক্ত করা যেতে পারে রেকর্ড না থাকলে সেরা পদ্ধতির সবসময় নয় আছে একসঙ্গে সংরক্ষণ করা হবে। আমার মনে হয় কিছু...


10

আমি এই স্ক্রিপ্টটি অন্য স্ট্যাকওভারফ্লো প্রশ্ন / উত্তর থেকে পেয়েছি:

SELECT SUM(p.rows) FROM sys.partitions AS p
  INNER JOIN sys.tables AS t
  ON p.[object_id] = t.[object_id]
  INNER JOIN sys.schemas AS s
  ON s.[schema_id] = t.[schema_id]
  WHERE t.name = N'YourTableNameHere'
  AND s.name = N'dbo'
  AND p.index_id IN (0,1);

আমার টেবিলের 500 মিলিয়ন রেকর্ড রয়েছে এবং উপরের 1 মিলের কম রিটার্ন রয়েছে। এদিকে,

SELECT COUNT(id) FROM MyTable

পুরো 39 মিনিট, 52 সেকেন্ড সময় লাগে!

তারা ঠিক একই সংখ্যক সারিতে ফল দেয় (আমার ক্ষেত্রে, ঠিক 519326012)।

আমি জানি না যে সর্বদা এটি হবে কিনা।


এই ক্যোয়ারির সাথে সারি গণনা পেতে আপনি কি কোনও পরামিতি যুক্ত করতে পারেন? উদাহরণ: আপনার জিজ্ঞাসার সাথে টেবিলের নাম থেকে COUNT (1) নির্বাচন করুন কলাম ফাইলড = '1'?
ভিএনডেভিল

এটি গণনা - সারিগুলির সংখ্যা (রেকর্ড) এই ক্ষেত্রে "গণনা"। "500 মিলিয়ন রেকর্ডস" একটি আনুমানিক সংখ্যা এবং "519326012" হ'ল সারি বা গণনার সঠিক সংখ্যা। সারি = রেকর্ড = গণনা।
জেকজে

9

আপনি এই sp_spaceused চেষ্টা করতে পারেন (লেনদেন- SQL)

সারণীর সংখ্যা, ডিস্কের স্থান সংরক্ষিত এবং বর্তমান ডাটাবেসে কোনও টেবিল, সূচিযুক্ত ভিউ বা পরিষেবা ব্রোকার সারি দ্বারা ব্যবহৃত ডিস্কের স্থান প্রদর্শন করে বা পুরো ডাটাবেস দ্বারা সংরক্ষিত এবং ব্যবহৃত ডিস্কের স্থান প্রদর্শন করে।


স্পিস্পেসযুক্ত কি আমাকে একটি আনুমানিক গণনা দেবে না?
স্বরঙ্গ সরমা

1
এফওয়াইআই: এটি sys.dm_db_partition_stats অভ্যন্তরীণভাবে ব্যবহার করে
gbn

6

যদি এসকিউএল সার্ভার সংস্করণটি 2005/2008 হয়, আপনি কোনও টেবিলে সারি গণনা গণনা করতে ডিএমভি ব্যবহার করতে পারেন:

-- Shows all user tables and row counts for the current database 
-- Remove is_ms_shipped = 0 check to include system objects 
-- i.index_id < 2 indicates clustered index (1) or hash table (0) 
SELECT o.name, 
 ddps.row_count 
FROM sys.indexes AS i 
 INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID 
 INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID 
 AND i.index_id = ddps.index_id 
WHERE i.index_id < 2 
 AND o.is_ms_shipped = 0 
ORDER BY o.NAME 

এসকিউএল সার্ভার 2000 ডাটাবেস ইঞ্জিনের জন্য, সিসিনডেক্সগুলি কাজ করবে তবে অদূর ভবিষ্যতে এটি সরিয়ে ফেলা হতে পারে বলে এসকিউএল সার্ভারের ভবিষ্যতের সংস্করণগুলিতে এটি ব্যবহার এড়াতে দৃ strongly়ভাবে পরামর্শ দেওয়া হচ্ছে।

থেকে নেওয়া নমুনা কোড: কীভাবে টেবিলের সারিগুলি দ্রুত এবং বেদাহীনভাবে গণনা করা যায়


এটি আনুমানিক সঠিক নয় : আমার উত্তর দেখুন দয়া করে
gbn

আপনি কি এমন উদাহরণ জানেন যেখানে এটি সঠিক নয়? আফাইক, এটি আপডেট করা পরিসংখ্যানের উপর নির্ভর করে না।
আলিরেজা মাদদা


5

আমি উত্তর হিসাবে অন্যদের মত বিশেষজ্ঞের কাছাকাছি আর নেই তবে আমি একটি পদ্ধতিটি নিয়ে টেবিল থেকে এলোমেলো সারিটি নির্বাচন করার জন্য ব্যবহার করছি (অত্যধিক প্রাসঙ্গিক নয়) তবে আমার রেফারেন্স সারণীতে সারিগুলির সংখ্যা জানতে আমার প্রয়োজনীয় ছিল র্যান্ডম সূচক গণনা করতে। Traditionalতিহ্যবাহী গণনা (*) বা গণনা (1) এর কাজটি ব্যবহার করে তবে আমার ক্যোয়ারীটি চালানোর জন্য আমি মাঝে মধ্যে 2 সেকেন্ড পর্যন্ত উঠছিলাম। সুতরাং পরিবর্তে ('tbl_HighOrder' নামক আমার টেবিলের জন্য) আমি ব্যবহার করছি:

Declare @max int

Select @max = Row_Count
From sys.dm_db_partition_stats
Where Object_Name(Object_Id) = 'tbl_HighOrder'

এটি দুর্দান্ত কাজ করে এবং ম্যানেজমেন্ট স্টুডিওতে ক্যোয়ারির সময়গুলি শূন্য।


1
এফডাব্লুআইডাব্লু, আপনি যে ডাটাবেস বিক্রেতাকে ব্যবহার করছেন তা উল্লেখ করা উচিত; আমি মনে করি বিক্রেতার উপর নির্ভর করে বিবৃতিটি কিছুটা আলাদা হবে।
টুলমেকারস্টেভ

5

ভাল, 5 বছর দেরীতে এবং এটি সহায়তা করে কিনা তা সম্পর্কে নিশ্চিত না:

আমি সংখ্যাটি গণনা করার চেষ্টা করছিলাম। এমএস এসকিউএল সার্ভার ম্যানেজমেন্ট স্টুডিও ব্যবহার করে একটি এসকিউএল সার্ভার টেবিলের সারিগুলির মধ্যে এবং কয়েকটি ওভারফ্লো ত্রুটিতে চলেছে, তারপরে আমি নীচে ব্যবহার করেছি:

নির্বাচন count_big [dbname] থেকে (1) [dbo] [FactSampleValue]।।

ফলাফল :

24296650578 সারি


5

আমি এই ভাল নিবন্ধটি এসকিউএল সার্ভার পেয়েছি – কীভাবে: টেবিলের জন্য দ্রুত সঠিক সারি গণনা পুনরুদ্ধার করুনmartijnh1 যা থেকে প্রতিটি পরিস্থিতির জন্য একটি ভাল পুনরুদ্ধার দেয়।

আমার এটি প্রসারিত করার দরকার যেখানে একটি নির্দিষ্ট শর্তের উপর ভিত্তি করে আমার একটি গণনা প্রদান করা প্রয়োজন এবং যখন আমি এই অংশটি দেখি, আমি এই উত্তরটি আরও আপডেট করব।

ইতিমধ্যে, নিবন্ধ থেকে বিবরণ এখানে:

পদ্ধতি 1:

প্রশ্ন:

SELECT COUNT(*) FROM Transactions 

মন্তব্যসমূহ:

একটি পূর্ণ টেবিল স্ক্যান করে। বড় টেবিলের উপর ধীর।

পদ্ধতি 2:

প্রশ্ন:

SELECT CONVERT(bigint, rows) 
FROM sysindexes 
WHERE id = OBJECT_ID('Transactions') 
AND indid < 2 

মন্তব্যসমূহ:

সারি গণনা পুনরুদ্ধার করার দ্রুত উপায়। পরিসংখ্যান উপর নির্ভর করে এবং সঠিক।

COUPROWS সহ ডিবিসিসি আপডেট আপডেট (ডাটাবেস) চালান, এটি বড় সারণীর জন্য উল্লেখযোগ্য সময় নিতে পারে।

পদ্ধতি 3:

প্রশ্ন:

SELECT CAST(p.rows AS float) 
FROM sys.tables AS tbl 
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and
idx.index_id < 2 
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int) 
AND p.index_id=idx.index_id 
WHERE ((tbl.name=N'Transactions' 
AND SCHEMA_NAME(tbl.schema_id)='dbo')) 

মন্তব্যসমূহ:

এসকিউএল পরিচালনার স্টুডিওতে যেভাবে সারি গণনা করা হয়েছে (সারণীর বৈশিষ্ট্য, সঞ্চয়স্থান, সারি গণনা দেখুন)। খুব দ্রুত, তবে এখনও সারিগুলির আনুমানিক সংখ্যা।

পদ্ধতি 4:

প্রশ্ন:

SELECT SUM (row_count) 
FROM sys.dm_db_partition_stats 
WHERE object_id=OBJECT_ID('Transactions')    
AND (index_id=0 or index_id=1); 

মন্তব্যসমূহ:

দ্রুত (যদিও 2 পদ্ধতি হিসাবে দ্রুত নয়) অপারেশন এবং সমানভাবে গুরুত্বপূর্ণ, নির্ভরযোগ্য।


ধন্যবাদ! সত্যিই দরকারী টিপ। সিস্টেম টেবিলগুলি দেখার আমার কাছে অনুমতি নেই তাই পদ্ধতি 4 আমার নয়। তবে পদ্ধতি 3 যথেষ্ট ভাল।
নিকোলাস হামফ্রে

3

আমি মনে করি না যে একটি সর্বদা দ্রুততম সমাধান রয়েছে: কিছু আরডিবিএমএস / সংস্করণে নির্দিষ্ট SELECT COUNT(*)বিকল্পগুলি ব্যবহারের জন্য নির্দিষ্ট অপ্টিমাইজেশন রয়েছে অন্যরা কেবল টেবিল-স্ক্যান করে। দ্বিতীয় সেটটির জন্য আপনাকে ডকুমেন্টেশন / সমর্থন সাইটগুলিতে যেতে হবে, যা সম্ভবত আরও কিছু নির্দিষ্ট ক্যোয়ারী রচনার প্রয়োজন হবে যা সাধারণত কোনওভাবে সূচককে হিট করে।

সম্পাদনা করুন:

আপনার স্কিমা এবং ডেটা বন্টনের উপর নির্ভর করে এখানে কাজ করা একটি চিন্তাভাবনা রয়েছে: আপনার কি এমন একটি সূচকযুক্ত কলাম রয়েছে যা একটি বর্ধমান মান, একটি সংখ্যাসূচক বর্ধমান আইডি, বলুন বা টাইমস্ট্যাম্প বা তারিখের উল্লেখ করে? তারপরে, ডিলিটগুলি ঘটবে না বলে ধরে নেওয়া, কিছু সাম্প্রতিক মান (গতকালের তারিখ, কিছু সাম্প্রতিক নমুনার পয়েন্টে সর্বোচ্চ আইডি মান) পর্যন্ত গণনা সংরক্ষণ করা এবং এর বাইরে গণনাটি যুক্ত করা উচিত যা সূচকে খুব দ্রুত সমাধান করা উচিত । অবশ্যই মান এবং সূচকগুলির উপর খুব নির্ভরশীল তবে এটি কোনও ডিবিএমএসের কোনও সংস্করণের জন্য প্রযোজ্য।


আমি খুব আশা করব যে কোনও শালীন ডিবিএমএস এর জন্য একটি সূচক ব্যবহার করবে SELECT COUNT(*)। এমনকি মাইএসকিউএল দৃশ্যত এটি করে ...
sleske

ভাবেন মুছে ফেলুন না - গুরুত্ব সহকারে ?? ; পি
টুলমেকারস্টেভ

3

আমি এই প্রশ্নে দেরি করছি, তবে আপনি এখানে মাইএসকিউএল দিয়ে কী করতে পারেন (যেমন আমি মাইএসকিউএল ব্যবহার করি)। আমি এখানে আমার পর্যবেক্ষণগুলি ভাগ করছি:

1) SELECT COUNT(*) AS TOTAL_ROWS FROM <TABLE_NAME>

ফলাফল
সারি গণনা: 508534
কনসোল আউটপুট: আক্রান্ত সারি: 0 সারি পাওয়া গেছে: 1 সতর্কতা: 0 1 প্রশ্নের জন্য সময়কাল: 0.125 সেকেন্ড।
সারি সংখ্যক সারি সহ একটি টেবিলের জন্য কিছুক্ষণ সময় নেয় তবে সারি গণনাটি খুব নির্ভুল।

2) SHOW TABLE STATUS or SHOW TABLE STATUS WHERE NAME="<TABLE_NAME>"

ফলাফল
সারি গণনা: 511235
কনসোল আউটপুট: আক্রান্ত সারি: 0 সারি পাওয়া গেছে: 1 সতর্কতা: 0 1 প্রশ্নের জন্য সময়কাল: 0.250 সেকেন্ড সংক্ষিপ্তসার: সারি গণনা সঠিক নয়।

3) SELECT * FROM information_schema.tables WHERE table_schema = DATABASE();

ফলাফল
সারি গণনা: 507806
কনসোল আউটপুট: আক্রান্ত সারি: 0 সারি পাওয়া গেছে: 48 সতর্কতা: 0 1 প্রশ্নের জন্য সময়কাল: 1.701 সেকেন্ড।
সারি গণনা সঠিক নয়।

আমি কোনও মাইএসকিউএল বা ডাটাবেস বিশেষজ্ঞ নই, তবে আমি পেয়েছি যে খুব বড় টেবিলের জন্য, আপনি বিকল্প 2 বা 3 ব্যবহার করতে পারেন এবং কতগুলি সারি রয়েছে তার একটি 'ন্যায্য ধারণা' পেতে পারেন।

ইউআইতে কিছু পরিসংখ্যান প্রদর্শন করার জন্য আমার এই সারি সংখ্যাগুলি পাওয়া দরকার। উপরের প্রশ্নগুলির সাথে, আমি জানতাম যে মোট সারিগুলি 500,000 এরও বেশি, সুতরাং আমি সারিগুলির সঠিক সংখ্যা না দেখিয়ে "500,000 এর বেশি সারি" এর মতো পরিসংখ্যান দেখিয়ে এসেছি।

আমি সম্ভবত ওপি-র প্রশ্নের উত্তর না দিয়েছি, তবে এমন পরিসংখ্যানের যে পরিস্থিতিতে দরকার ছিল এমন পরিস্থিতিতে আমি যা করেছি তা ভাগ করে নিচ্ছি। আমার ক্ষেত্রে, আনুমানিক সারিগুলি দেখানো গ্রহণযোগ্য ছিল এবং তাই উপরেরটি আমার পক্ষে কাজ করেছিল।


2

ঠিক কোনও ডিবিএমএস-অজোনস্টিক সমাধান নয়, তবে কমপক্ষে আপনার ক্লায়েন্ট কোডটি পার্থক্যটি দেখতে পাবে না ...

একটি সারি এবং একটি পূর্ণসংখ্যার ক্ষেত্র এন 1 এর সাথে অন্য একটি সারণী টি তৈরি করুন এবং সন্নিবিষ্ট ট্রিগার তৈরি করুন যা কেবল কার্যকর করে:

UPDATE T SET N = N + 1

কার্যকর করে এমন একটি বিলোপ ট্রিগারও তৈরি করুন:

UPDATE T SET N = N - 1

এর লবণের মূল্যের একটি ডিবিএমএস 2 টির উপরে ক্রিয়াকলাপগুলির পারমাণবিকতার গ্যারান্টি দিবে এবং এন সর্বকালে সারিগুলির সঠিক গণনা রাখবে যা কেবল তখনই পাওয়া খুব দ্রুত:

SELECT N FROM T

ট্রিগারগুলি ডিবিএমএস-নির্দিষ্ট হলেও, টি থেকে নির্বাচন করা নয় এবং প্রতিটি ক্লায়েন্ট কোডকে প্রতিটি সমর্থিত ডিবিএমএসের জন্য পরিবর্তন করার প্রয়োজন হবে না।

তবে, টেবিলটি INSERT বা ডিলেট-নিবিড় হয় যদি এটি সন্নিবেশ / মোছার পরে অবিলম্বে কমিট না করে থাকে তবে এর কিছু স্কেলিবিলিটি সমস্যা থাকতে পারে।


1 এই নামগুলি কেবল স্থানধারক - উত্পাদনে আরও অর্থপূর্ণ কিছু ব্যবহার করুন।

2 যেমন N পড়া এবং লেখার মধ্যবর্তী একযোগে লেনদেন দ্বারা N পরিবর্তন করা যায় না, যতক্ষণ না পড়া এবং লেখা উভয়ই একক এসকিউএল স্টেটমেন্টে করা হয়।


2

একটি আক্ষরিক উন্মাদ উত্তর, তবে যদি আপনার কাছে কোনও ধরণের প্রতিলিপি ব্যবস্থা স্থাপন করা হয় (এক বিলিয়ন সারিযুক্ত একটি সিস্টেমের জন্য, আমি আশা করি আপনি এটি করেন) তবে আপনি মোটামুটি অনুমানকারী (যেমন MAX(pk)) ব্যবহার করতে পারেন , দাসের সংখ্যার মাধ্যমে সেই মানটি ভাগ করতে পারেন আপনার কাছে সমান্তরালভাবে বেশ কয়েকটি ক্যোয়ারী চালান।

বেশিরভাগ ক্ষেত্রে, আপনি সর্বাধিক কী (অথবা আমার অনুমিত প্রাথমিক কী) এর উপর ভিত্তি করে দাসগুলিতে ক্যোয়ারীগুলি বিভাজন করতে পারেন (আমরা আমাদের সারি / দাস হিসাবে 250000000 ব্যবহার করব):

-- First slave
SELECT COUNT(pk) FROM t WHERE pk < 250000000
-- Ith slave where 2 <= I <= N - 1
SELECT COUNT(pk) FROM t WHERE pk >= I*250000000 and pk < (I+1)*250000000
-- Last slave
SELECT COUNT(pk) FROM t WHERE pk > (N-1)*250000000

তবে আপনার কেবল এসকিউএল প্রয়োজন। কি বক্ষ! ঠিক আছে, সুতরাং যাক আপনি একটি সাদোমাচোস্ট। মাস্টার (বা নিকটতম দাস) এ আপনি সম্ভবত এর জন্য একটি সারণী তৈরি করতে হবে:

CREATE TABLE counter_table (minpk integer, maxpk integer, cnt integer, slaveid integer)

সুতরাং আপনার দাসদের মধ্যে কেবল বাছাইকারীদের চালনার পরিবর্তে, আপনাকে এর সাদৃশ্য একটি সন্নিবেশ করতে হবে:

INSERT INTO counter_table VALUES (I*25000000, (I+1)*250000000, (SELECT COUNT(pk) FROM ... ), @@SLAVE_ID)

আপনি দাসদের মাস্টারে একটি টেবিলে লেখার বিষয়ে সমস্যা নিয়ে যেতে পারেন। আপনার আরও বেশি সাদিসের দরকার হতে পারে- মানে সৃজনশীল:

-- A table per slave!
INSERT INTO counter_table_slave_I VALUES (...)

প্রথম দাসের তুলনায় আপনার প্রতিদ্বন্দ্বী গ্রাফ দ্বারা অনুসরণ করা পথে শেষ অবধি একটি দাস থাকা উচিত। এই দাসের এখন অন্যান্য সমস্ত পাল্টা মান থাকতে হবে এবং এর নিজস্ব মান থাকতে হবে। তবে আপনি শেষ করার পরে, সম্ভবত সারিগুলি যুক্ত হবে, সুতরাং আপনার কাউন্টার_সামগ্রী এবং বর্তমান সর্বাধিক পিকেটে রেকর্ডকৃত সর্বাধিক পিকে ক্ষতিপূরণ দেওয়ার জন্য আপনাকে আর একটি প্রবেশ করানো উচিত।

এই মুহুর্তে, মোট সারিগুলি কী তা নির্ধারণ করার জন্য আপনাকে একটি সামগ্রিক ফাংশন করতে হবে, তবে এটি সহজ যেহেতু আপনি সর্বাধিক "আপনার যে দাসের সংখ্যা এবং সারি পরিবর্তন" সারিটি চালিয়ে যাচ্ছেন।

আপনি যদি দাসদের মধ্যে পৃথক সারণী থাকে এমন পরিস্থিতিতে থাকেন তবে UNIONআপনার প্রয়োজনীয় সমস্ত সারি পেতে পারেন ।

SELECT SUM(cnt) FROM (
    SELECT * FROM counter_table_slave_1
      UNION
    SELECT * FROM counter_table_slave_2
      UNION
    ...
  )

অথবা আপনি জানেন, কিছুটা কম উন্মাদ হয়ে আপনার বিতরণকারী প্রক্রিয়াকরণ সিস্টেমে ডেটা মাইগ্রেট করুন বা সম্ভবত ডেটা গুদামজাতকরণ সমাধান ব্যবহার করুন (যা আপনাকে ভবিষ্যতেও দুর্দান্ত ডেটা ক্রাঞ্চিং দেবে)।

মনে রাখবেন, এটি আপনার প্রতিলিপিটি কতটা ভাল সেট আপ করা হয়েছে তার উপর নির্ভর করে। যেহেতু প্রাথমিক বাধা হ'ল সম্ভবত ধ্রুবক স্টোরেজ হবে, যদি আপনার ভারী প্রতিবেশী শব্দে ক্রুডি স্টোরেজ বা দুর্বলভাবে পৃথক পৃথক ডেটা স্টোর থাকে, তবে এটি সম্ভবত একটি মাত্র অপেক্ষা করার চেয়ে ধীর গতিতে চলবে runSELECT COUNT(*) ...

তবে আপনার যদি ভাল প্রতিলিপি থাকে, তবে আপনার গতির লাভগুলি সরাসরি সংখ্যার বা দাসদের সাথে সম্পর্কিত হওয়া উচিত। প্রকৃতপক্ষে, যদি একা গণনা ক্যোয়ারী চালাতে 10 মিনিট সময় লাগে এবং আপনার 8 জন ক্রীতদাস থাকে তবে আপনি আপনার সময়টি কয়েক মিনিটেরও কম কমাতে চাইবেন। সম্ভবত এই সমাধানটির বিশদটি প্রকাশ করতে এক ঘন্টা।

অবশ্যই, আপনি কখনই সত্যিই আশ্চর্যজনক সঠিক উত্তর পাবেন না কেননা এই বিতরণ সমাধানটি বেশিরভাগ সময় সীমাবদ্ধ করে যেখানে সারিগুলি মোছা এবং সন্নিবেশ করা যায়, তবে আপনি একই পরিস্থিতিতে সারিগুলির বিতরণ লক পেতে চেষ্টা করতে পারেন এবং একটি নির্দিষ্ট গণনা পেতে পারেন একটি নির্দিষ্ট মুহুর্তের জন্য টেবিলে সারিগুলির।

আসলে এটি অসম্ভব বলে মনে হচ্ছে, যেহেতু আপনি মূলত একটি এসকিউএল-কেবল সমাধান নিয়েই আটকে আছেন এবং আমি মনে করি না যে আপনি তাত্ক্ষণিকভাবে একাধিক ক্রীতদাস জুড়ে শার্পড এবং লক করা কোয়েরি চালানোর জন্য একটি ব্যবস্থা সরবরাহ করেছেন। সম্ভবত যদি আপনি রেপ্লিকেশন লগ ফাইলের নিয়ন্ত্রণ রাখেন ... যার অর্থ আপনি এই উদ্দেশ্যে আক্ষরিক অর্থেই ক্রীতদাসদের সজ্জিত করতেন, এটি কোনও সন্দেহ নেই যে কোনওভাবেই কেবল একটি একক মেশিনে গণনা কোয়েরি চালানোর চেয়ে ধীর।

সুতরাং আমার দুটি 2013 পেনিস আছে।


2

যদি সন্নিবেশ ট্রিগারটি ব্যবহার করা খুব ব্যয়বহুল হয় তবে একটি মোছার ট্রিগারটি সরবরাহ করা যেতে পারে এবং একটি স্বয়ংক্রিয়-বৃদ্ধি রয়েছেid , তারপরে একবার পুরো টেবিলটি একবার গণনা করার পরে এবং গণনাটি last-countএবং তার হিসাবে মনে রাখার পরে last-counted-id,

তারপরে প্রতিটি দিনের জন্য কেবল গণনা করা প্রয়োজন id> এতে last-counted-idযোগ করুন last-countএবং নতুন সঞ্চয় করুন last-counted-id

মুছে ফেলা ট্রিগারটি সর্বশেষ গণনায় হ্রাস পাবে, যদি মুছে ফেলা রেকর্ডের আইডি <= সর্বশেষ-গণনা-আইডি।


.. দুঃখিত, যে এসকিউএল ব্যবহৃত হবে তা দেখানোর জন্য সময় নেই (আমার এসকিউএলটি মরিচা হয়)। যদি কেউ এসকিউএল যুক্ত করতে আমার উত্তর সম্পাদনা করতে চায় তবে তা দুর্দান্ত হবে!
টুলমেকারস্টেভ

1

আপনার যদি অটো-ইনক্রিমেন্টিং প্রাথমিক কী কলামে কোনও সারণী কাঠামো থাকে যার মধ্যে সারিগুলি কখনই মোছা হয় না, রেকর্ড গণনা নির্ধারণ করার জন্য নিম্নলিখিতটি দ্রুততম উপায় এবং বেশিরভাগ এএনএসআই অনুবর্তী ডেটাবেসগুলিতে একইভাবে কাজ করা উচিত:

SELECT TOP(1) <primarykeyfield> FROM <table> ORDER BY <primarykeyfield> DESC;

আমি এমএস এসকিউএল টেবিলগুলির সাথে বিলিয়ন বিলিয়ন সারি রয়েছে যা রেকর্ড গণনা সহ ডেটা জন্য সাব-সেকেন্ড প্রতিক্রিয়া সময় প্রয়োজন require অনুরূপ নির্বাচন করুন COUNT (*) তুলনা করে প্রক্রিয়া করতে কয়েক মিনিট সময় নেয়।


1
পুরোপুরি সত্য নয় - কোনও INSERTলেনদেন আবার ঘুরিয়ে দিলে কী হয়? সেই প্রাথমিক কী মানটি অনুপস্থিত থাকবে, তাই প্রকৃত রেকর্ড গণনাটি সর্বাধিক মানের চেয়ে এক কম হবে।
স্যার ক্রিসপলট

ক্রম ফাঁক হতে পারে। সাধারণত রোলব্যাকের ফলাফল।
ওসায় ই

প্রকৃতপক্ষে, এই উত্তরের একটি পরিবর্তন রয়েছে যা তুলনায় উল্লেখযোগ্যভাবে দ্রুত হতে পারে count(*), যদি কোনও ডাটাবেস বিক্রেতাই যথেষ্ট পরিমাণে অনুকূলিত না হন count(*): প্রতিটি দিন সর্বশেষ স্বতঃ-সূচক এবং তার সাথে সম্পর্কিত গণনা সম্পর্কে নজর রাখেন, তবে অতীতের রেকর্ডগুলির একটি গণনা জিজ্ঞাসা করুন। এছাড়াও হ্যান্ডেল করতে পারি deleteগুলি যদি decrements মুছে একটি ট্রিগার যোগ পূর্ববর্তী , যদি মুছে ফেলা রেকর্ড আইডি <= যে গত স্বয়ংক্রিয় সূচক মোট।
টুলমেকারস্টেভ

1

SQL সার্ভারের জন্য এটি ব্যবহার করে দেখুন

SELECT T.name, 
       I.rows AS [ROWCOUNT] 
FROM   sys.tables AS T 
       INNER JOIN sys.sysindexes AS I 
               ON T.object_id = I.id AND I.indid < 2 
WHERE T.name = 'Your_Table_Name'
ORDER  BY I.rows DESC 

0

সিসিনডেক্স থেকে সারি নির্বাচন করুন যেখানে আইডি = অবজেক্ট_আইডি ('টেবিলনেম') এবং <2 ইনডিড


0

কিছু কলামে একটি সূচক রাখুন। এটি অপ্টিমাইজারটিকে টেবিলের সম্পূর্ণ স্ক্যানের পরিবর্তে সূচক ব্লকগুলির একটি সম্পূর্ণ স্ক্যান করতে দেয় should এটি আপনার আইও ব্যয়কে কমিয়ে দেবে। কার্যকর করার পরিকল্পনাটি আগে এবং পরে দেখুন। তারপরে প্রাচীর ঘড়ির সময় উভয় উপায়ে পরিমাপ করুন।


যদি কোনও টেবিলে কোনও কলামে কোনও সূচক ছাড়াই কয়েক বিলিয়ন সারি থাকে, তবে মূল প্রশ্নে প্রকাশিত প্রয়োজনের বাইরে ব্যাপক কর্মক্ষমতা সংক্রান্ত সমস্যা দেখা দেবে .. তবে ভাল যে আপনি উল্লেখ করেছেন (কিছুই ধরে
নিবেন

0

যদি আপনি ওরাকল ব্যবহার করেন তবে এটি সম্পর্কে কীভাবে (ধরে নিচ্ছেন টেবিলের পরিসংখ্যান আপডেট হয়েছে):

select <TABLE_NAME>, num_rows, last_analyzed from user_tables

সর্বশেষ_নালিজেডগুলি কখন পরিসংখ্যানগুলি সর্বশেষ সংগ্রহ করা হয়েছিল তা দেখায়।


0

পোস্টগ্র্যাস এসকিউএল সহ:

SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = 'table_name'

-1

এসকিউএল সার্ভার ২০১ 2016-এ, আমি কেবল সারণির বৈশিষ্ট্যগুলি পরীক্ষা করতে পারি এবং তারপরে 'স্টোরেজ' ট্যাবটি নির্বাচন করতে পারি - এটি আমাকে সারি গণনা, টেবিল দ্বারা ব্যবহৃত ডিস্ক স্থান, ব্যবহৃত সূচক স্থান ইত্যাদি দেয় gives


তিনি একটি খুঁজছিলেন database vendor independent solution। এছাড়াও এটির জন্য একটি জিইউআই প্রয়োজন এবং স্বয়ংক্রিয় করা যাবে না। এছাড়াও এটি COUNT (*) হিসাবে দ্রুত নয়
ফ্রাইডার

-3

কিছুটা দেরি হতে পারে তবে এটি এমএসএসকিউএল এর জন্য অন্যকে সহায়তা করতে পারে

; রেকর্ডকাউন্ট হিসাবে AS (নির্বাচন করুন ROW_NUMBER () ওভার (COLUMN_NAME দ্বারা অর্ডার) হিসাবে [টেবিলের মাধ্যমে RowNumber] নির্বাচন করুন ম্যাক্স (RowNumber) থেকে রেকর্ডকাউন্ট


এটি COUNT () এর চেয়ে উল্লেখযোগ্য পরিমাণে সবচেয়ে খারাপ, যদি না আমরা খুব ভাগ্যবান এবং অপ্টিমাইজার এটি একটি COUNT () এ অনুকূলিত করতে পরিচালিত হয় - কেন এলোমেলো কলামে SORT এ জিজ্ঞাসা করব?!?!
dsz
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.