কেন InnoDB সারি গণনা সঞ্চয় করে না?


19

সকলেই জানেন যে টেবিলগুলিতে ইঞ্জিন হিসাবে InnoDB ব্যবহার করে, এর মতো কোয়েরিগুলি SELECT COUNT(*) FROM mytableখুব নিখরচায় এবং খুব ধীর হয়, বিশেষত যখন টেবিলটি বড় হয়ে যায় এবং যখন এই ক্যোয়ারী কার্যকর হয় তখন ধ্রুব সারি সন্নিবেশ / মোছা থাকে।

আমি এটি বুঝতে পেরেছি, InnoDB একটি অভ্যন্তরীণ ভেরিয়েবলে সারি গণনা সংরক্ষণ করে না, যা এই সমস্যার কারণ।

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

পিএস: আমি ডিবিগুলিতে বিশেষজ্ঞ নই, আমি কেবল একজন যার শখের মাইএসকিউএল রয়েছে। সুতরাং আমি যদি কেবল বোকা কিছু জিজ্ঞাসা করি, অতিরিক্ত সমালোচনা করবেন না: ডি।


6
আস্তে, হ্যাঁ অনর্থক, না। এটি ধীর কারণ এটি সঠিক ফলাফল দেয়। আপনার যখন 200 এম সারির টেবিল রয়েছে এবং সম্ভবত একই সারণীতে সন্নিবেশ / মুছতে থাকা অন্যান্য অনেক লেনদেন, সম্ভবত প্রতি সেকেন্ডে অনেকগুলি সারি, অন্য প্রশ্নটি হয় "আপনার সঠিক সংখ্যাটি দরকার?"
ypercubeᵀᴹ

@ টাইপকুব আমি জানি আমি phpmyadmin এ কয়েকবার কয়েকটি সারি গণনা মান দেখেছি যা খুব বন্ধ ছিল। এছাড়াও, সেখানে একটি মন্তব্য রয়েছে যা বলে "সঠিক হতে পারে না" something
রাদু মুর্জিয়া

1
@ রাদুমুরজিয়া পিএইচপিএমআইএডমিন ব্যবহারকারীরা আপনার যে গতির কারণ সম্পর্কে জানবেন তার জন্য ইনোডিবি টেবিলের জন্য টেবিলের গণনা করার একটি বিকল্প পদ্ধতি ব্যবহার করে। এইখানেই আপনি উল্লেখ করেছেন যে অসচ্ছলতা কার্যকর হয়েছে। আসল SELECT COUNT(*) FROM ...প্রশ্নগুলি সুনির্দিষ্ট। আপনি যদি পছন্দ করেন তবে phpMyAdmin গতিতে ব্যয় করে সর্বদা সঠিক সারি গণনা ব্যবহার করার জন্য কনফিগার করা যেতে পারে। আরো তথ্য: stackoverflow.com/questions/11926259/...
DOOManiac

উত্তর:


9

আমি @ রেমাসরুসানু (তার উত্তরের জন্য +1) এর সাথে একমত

SELECT COUNT(*) FROM mydb.mytableInnoDB তে লেনদেনের স্টোরেজ ইঞ্জিনের মতো আচরণ করে। এটি মাইআইএসএএম এর সাথে তুলনা করুন।

MyISAM

যদি mydb.mytableএকটি MyISAM টেবিল, লঞ্চ SELECT COUNT(*) FROM mydb.mytable;মাত্র চলমান মত হল SELECT table_rows FROM information_schema.table WHERE table_schema = 'mydb' AND table_name = 'mytable';। এটি মাইআইএসএএম টেবিলের শিরোনামে সারি গণনার দ্রুত অনুসন্ধান শুরু করে।

InnoDB

যদি mydb.mytableকোনও InnoDB টেবিল হয়, আপনি যা চলছে তা হজ-পড পাবেন। নিম্নলিখিতগুলি পরিচালনা করে আপনার এমভিসিসি চলছে:

  • ib_logfile0 / ib_logfile1 (পুনরায় লগগুলি)
  • ibdata1
    • লগগুলি পূর্বাবস্থায় ফেরান
    • রোলব্যাক
    • ডেটা অভিধানের পরিবর্তনসমূহ ges
  • বাফার পুল পরিচালনা
  • লেনদেনের বিচ্ছিন্নতা (4 প্রকারের)
    • পুনরাবৃত্তিযোগ্য পাঠ
    • প্রতিশ্রুতিবদ্ধ পড়ুন
    • অনুপস্থিত পড়ুন
    • Serializable

একটি টেবিল গণনার জন্য InnoDB জিজ্ঞাসা করার জন্য এই অশুভ জিনিসগুলির মাধ্যমে নেভিগেশন প্রয়োজন। প্রকৃতপক্ষে, কেউ কখনও সত্যই জানে না SELECT COUNT(*) from mydb.mytableযে কেবল পুনরাবৃত্তযোগ্য পাঠযোগ্য গণনা করা হয় বা প্রতিশ্রুতিবদ্ধ পড়া এবং যেগুলি অনিযুক্ত রয়েছে তার অন্তর্ভুক্ত থাকে।

আপনি ইনোডাব_স্ট্যাটস_অন_মেডাটাটা সক্ষম করে জিনিসগুলিকে কিছুটা স্থিতিশীল করার চেষ্টা করতে পারেন

ইনোডাব_স্ট্যাটস_অন_মেটা_ডেটা মাইএসকিউএল ডকুমেন্টেশন অনুসারে

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

এটি নিষ্ক্রিয় করা আপনাকে এক্সপ্ল্যান পরিকল্পনাগুলি সেট আপ করার ক্ষেত্রে আপনাকে আরও স্থিতিশীল গণনা দিতে পারে বা নাও দিতে পারে। এটি SELECT COUNT(*) from mydb.mytableকোনও ভাল উপায়ে, খারাপ উপায়ে বা একেবারেই না পারফরম্যান্সকে প্রভাবিত করতে পারে । চেষ্টা করে দেখুন !!!


16

স্টার্টারের জন্য কোনও চলকটিতে সঞ্চয় করার জন্য 'কারেন্ট কাউন্ট' বলে কোনও জিনিস নেই। এর মতো একটি কোয়েরি SELECT COUNT(*) FROM ...বর্তমান বিচ্ছিন্নতা স্তর এবং সমস্ত সমবর্তী বিচারাধীন লেনদেনের সাপেক্ষে। বিচ্ছিন্নতা স্তরের উপর নির্ভর করে কোয়েরিটি অপ্রকাশিত লেনদেনের মাধ্যমে সারি সন্নিবেশ করা বা মোছা দেখতে বা দেখতে পারে না। উত্তর দেওয়ার একমাত্র উপায় হ'ল বর্তমান লেনদেনে দৃশ্যমান সারিগুলি গণনা করা।

মনে রাখবেন যে আমি গণনা চলাকালীন শুরু বা শেষ হওয়া সমবর্তী লেনদেনের আরও কাঁটাযুক্ত বিষয়টিকে স্পর্শও করি নি । রোলব্যাকের উল্লেখ না করা ...


1
ঠিক আছে, সুতরাং এটি বিচ্ছিন্নতার স্তরের উপর নির্ভরশীল, এটি উপলব্ধি করে। তবে এটি এখনও কার্যকর করা যেতে পারে।
রাদু মুর্জিয়া

@ সোবোলান এটির কারণ না হওয়া এবং না হওয়ার প্রচুর কারণ রয়েছে যার বেশিরভাগ উপরে উপরে তালিকাভুক্ত রয়েছে। আপনি কি লেনদেন শুরু (প্রতিটি ওরাকলের এসসিএন মাইএসকিউএল-তে থাকা) টেবিলের জন্য গণনাগুলির তালিকা বজায় রেখে এটি বাস্তবায়ন করবেন? এই জাতীয় গণনাগুলি পরিচালনা করা একটি বিশাল ওভারহেড হবে - একই টেবিলে প্রতিটি পরিমাণে বড় পরিমাণে INSERT / ডিলিট করে 100s বা সমকালীন সেশনগুলির সংখ্যা সহ একটি ডাটাবেস সম্পর্কে চিন্তা করুন। বজায় রাখা অসম্ভব।
ফিলি

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

3
@ জ্যাকডুগলাস আকর্ষণীয়। আমি আগের COUNT(*)জিজ্ঞাসাগুলিতে যা দেখেছি সেগুলি থেকে বাস্তবে খুব কমই প্রয়োজন হয় এবং সাধারণত বিকাশকারী অনভিজ্ঞতার ফলাফল হয় (সারিগুলি নির্বাচন করার আগে তাদের গণনা করুন!) বা খারাপ অ্যাপ্লিকেশন ডিজাইন।
ফিলি

1
@ সোবোলান - না, তা হবে না। একটি পরিষেবা থাকা যা পূর্বনির্ধারিত সময়ের ব্যবধানে এক ধরণের পরিসংখ্যানের টেবিলকে আপডেট করে much কল্পনা করুন যে একটি বৃহত ডাটাবেস এবং বেশ কয়েকটি প্রশাসক বেশিরভাগ টেবিলের সাহায্যে জিজ্ঞাসা করছেন, টেবিলটিতে SELECT COUNT(*)একটি অপ্টিমাইজড যুক্ত করুন WHEREএবং আপনার কাছে কয়েকটি প্রশ্নবিদ্ধ-কার্যকর স্ট্যাটাস কাউন্টারগুলির জন্য ডিবিকে তার হাঁটুতে আনবে।
এনবি

0

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

মাইআইএসএএম ইতিমধ্যে টেবিল স্তর লকিং করে, সুতরাং সেখানে কোনও অতিরিক্ত ব্যয় হবে না।

আমি খুব কমই একটি টেবিলের জন্য একটি সারি গণনা প্রয়োজন, যদিও আমি বেশ খানিকটা COUNT (*) ব্যবহার করি। আমার সাধারণত একটি WHERE ক্লজ যুক্ত থাকে। একটি ছোট ফলাফলের সেটটিতে দক্ষ সূচক ব্যবহার করে, আমি দেখতে পাচ্ছি যে তারা যথেষ্ট দ্রুত're

আমি একমত নই যে গণনাগুলি সঠিক নয় urate গণনাগুলি ডেটাগুলির একটি স্ন্যাপশটের প্রতিনিধিত্ব করে এবং আমি সর্বদা সেগুলি যথাযথ বলে খুঁজে পেয়েছি।

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


2
এটা না একটি লেনদেনজনিত সিস্টেমের মধ্যে সারি সঠিক গণনা রাখার সম্ভব। কারণ সক্রিয় লেনদেনের মতো অনেকগুলি পৃথক (এবং সঠিক) সারি অ্যাকাউন্ট রয়েছে।
a_horse_with_no_name

5
আমি যদিও এখানে '1 'দিয়েছি, যদিও এর সহজ সমাধানটি সম্ভবত মাইস্যামে স্যুইচ করা। আমি কখনই সারি গণনা পাওয়ার জন্য মাইআইএসএএম এ স্যুইচ করার পরামর্শ দেব না।
ডেরেক ডাউনি

@ a_horse_with_no_name, সুতরাং আপনি সম্মত হন যে প্রতিটি লেনদেনের জন্য একটি "সঠিক" সারি গণনা থাকবে। আমার কাছে সম্ভব বলে মনে হচ্ছে
মার্কাস অ্যাডামস

1
@ ডিস্টেস্ট, আমি কখনই "সারি গণনা পেতে" বলিনি।
মার্কাস অ্যাডামস

@ a_horse_with_no_name, এটি ঠিক মনে হচ্ছে না। নিশ্চয় আমরা কেবল সারি যখন লেনদেন পায় সংখ্যা গণনা করা হয় অঙ্গীকারবদ্ধ ঠিক আছে?
পেসারিয়ার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.