উত্তর:
https://dev.mysql.com/doc/refman/8.0/en/insert-optimization.html
সারি সন্নিবেশ করানোর জন্য প্রয়োজনীয় সময়টি নিম্নলিখিত বিষয়গুলি দ্বারা নির্ধারিত হয়, যেখানে সংখ্যাগুলি আনুমানিক অনুপাত নির্দেশ করে:
- সংযুক্ত হচ্ছে: (3)
- সার্ভারে ক্যোয়ারী পাঠানো হচ্ছে: (2)
- পার্সিং কোয়েরি: (2)
- সারি সন্নিবেশ করা হচ্ছে: (সারিটির 1 × আকার)
- সূচকগুলি সন্নিবেশ করানো: (সূচির সংখ্যা 1))
- সমাপ্তি: (1)
এ থেকে এটি সুস্পষ্ট হওয়া উচিত, একটি বৃহত বিবৃতি প্রেরণ আপনাকে প্রতি সন্নিবেশ বিবৃতিতে 7 এর ওভারহেড সংরক্ষণ করবে, যা পাঠটি আরও পড়তে আরও বলে:
আপনি যদি একই ক্লায়েন্ট থেকে একই সাথে অনেকগুলি সারি সন্নিবেশ করিয়ে থাকেন তবে একসাথে একাধিক সারি সন্নিবেশ করানোর জন্য একাধিক ভ্যালু তালিকা সহ INSERT বিবৃতি ব্যবহার করুন। পৃথক একক-সারি INSERT বিবৃতি ব্যবহার না করে এটি যথেষ্ট দ্রুত (কিছু ক্ষেত্রে অনেকগুণ দ্রুত)।
আমি জানি আমি এই প্রশ্নের জিজ্ঞাসা করার প্রায় আড়াই বছর পরে উত্তর দিচ্ছি, তবে আমি এখনই এমন একটি প্রকল্প থেকে কিছু হার্ড ডেটা সরবরাহ করতে চেয়েছিলাম যেটা এখনই কাজ করছি যা দেখায় যে প্রতি সন্নিবেশে একাধিক ভ্যালু ব্লক করা অনেক বেশি ক্রমযুক্ত একক VALUE ব্লক INSERT বিবৃতিগুলির চেয়ে দ্রুত।
সি # তে এই বেঞ্চমার্কের জন্য আমি যে কোডটি লিখেছি তাতে এমএসএসকিউএল ডেটা উত্স (~ 19,000 সারি, সমস্ত কোনও লেখা শুরু হওয়ার আগেই পড়ে নেওয়া হয়), এবং মাইএসকিউএল। নেট সংযোগকারী (মাইএসকিএল.ডাটা। *) স্টাফ থেকে তথ্য পড়তে ওডিবিসি ব্যবহার করে প্রস্তুত বিবৃতি দিয়ে মাইএসকিউএল সার্ভারের একটি টেবিলের মধ্যে মেমরি থেকে ডেটা লিখুন। এটি এমনভাবে লেখা হয়েছিল যাতে আমাকে প্রস্তুত করা INSERT অনুযায়ী ভ্যালু ব্লকের সংখ্যাটি গতিশীলভাবে সামঞ্জস্য করতে দেয় (যেমন, একটি সময়ে এন সারিগুলি সন্নিবেশ করান, যেখানে আমি রানের আগে এন এর মান সামঞ্জস্য করতে পারি।) আমি পরীক্ষাটিও চালিয়েছি প্রতিটি এন এর জন্য একাধিক বার
একক VALUE ব্লক করতে (উদাহরণস্বরূপ, একবারে 1 সারি) চালাতে 5.7 - 5.9 সেকেন্ড সময় নিয়েছিল। অন্যান্য মানগুলি নিম্নরূপ:
একসাথে 2 টি সারি: 3.5 - 3.5 সেকেন্ডে
একবারে 5 সারি: 2.2 - 2.2 সেকেন্ডে
একবারে 10 সারি: 1.7 - 1.7 সেকেন্ডে
একবারে 50 টি সারি: 1.17 - 1.18 সেকেন্ডে
একবারে 100 সারি: 1.1 - 1.4 সেকেন্ড
একবারে 500 টি সারি: 1.1 - 1.2 সেকেন্ডে
1000 সারি একবারে: 1.17 - 1.17 সেকেন্ড
সুতরাং হ্যাঁ, এমনকি কেবল 2 বা 3 একসাথে লেখার গতিতে নাটকীয় উন্নতি উপলব্ধ করা হয় (এন এর একটি উপাদান দ্বারা রানটাইম কাটা), যতক্ষণ না আপনি কোথাও n = 5 এবং n = 10 এর মধ্যে পৌঁছান, যেখানে উন্নতিটি স্পষ্টভাবে বন্ধ হয়ে যায়, এবং কোথাও n = 10 থেকে n = 50 সীমাতে উন্নতি নগণ্য হয়ে যায়।
আশা করে যে লোকেরা (ক) মাল্টিপ্রেয়ার ধারণাটি ব্যবহার করতে পারে কিনা এবং (খ) বিবৃতি অনুযায়ী কতগুলি ভ্যালু ব্লক তৈরি করতে পারে তা ধরে নিয়ে সহায়তা করে (ধরে নিয়েছে যে আপনি কোয়েরিটিকে সর্বাধিক ক্যোয়ারের আকারের অতীতের তুলনায় যথেষ্ট বড় হতে পারে এমন ডেটা দিয়ে কাজ করতে চান) মাইএসকিউএল-এর জন্য, যা আমি বিশ্বাস করি যে সার্ভারে ম্যাক্স_নিলেড_প্যাকেটের সেটটির মানের উপর নির্ভর করে অনেক জায়গায় ডিফল্টরূপে 16MB, সম্ভবত বড় বা ছোট))
একটি বড় কারণ হ'ল আপনি কোনও লেনদেনের ইঞ্জিন ব্যবহার করছেন কিনা এবং আপনার অটোকমিট চালু আছে কিনা।
ডিফল্টরূপে স্বতঃপাদন চালু রয়েছে এবং আপনি সম্ভবত এটি ছেড়ে যেতে চান; অতএব, প্রতিটি সন্নিবেশ করান যে আপনি এটি নিজস্ব লেনদেন করেন। এর অর্থ এই যে আপনি যদি প্রতি সারিতে একটি সন্নিবেশ করান তবে আপনি প্রতিটি সারির জন্য একটি লেনদেন করছেন।
একটি একক থ্রেড ধরে নেওয়া, এর অর্থ হ'ল সার্ভারকে প্রতিটি ROW এর জন্য ডিস্কে কিছু ডেটা সিঙ্ক করতে হবে। অবিচ্ছিন্ন স্টোরেজ স্থানে পৌঁছানোর জন্য ডেটার জন্য অপেক্ষা করতে হবে (আশা করি আপনার রেড কন্ট্রোলারে ব্যাটারি-ব্যাকড রাম)। এটি সহজাতভাবে বরং ধীর এবং সম্ভবত এই ক্ষেত্রে সীমাবদ্ধ ফ্যাক্টর হয়ে যাবে।
আমি অবশ্যই ধরে নিচ্ছি যে আপনি একটি লেনদেনের ইঞ্জিন ব্যবহার করছেন (সাধারণত ইনডোডব) এবং স্থায়িত্ব হ্রাস করার জন্য আপনি সেটিংসটি টিক করেননি।
আমি এটাও ধরে নিচ্ছি যে আপনি এই সন্নিবেশগুলি করতে একক থ্রেড ব্যবহার করছেন। একাধিক থ্রেড ম্যাডিজ জিনিসগুলি কিছুটা ব্যবহার করা কারণ মাইএসকিউএলের কয়েকটি সংস্করণ ইনোডাব-এ গ্রুপ-কমিটের কাজ করে - এর অর্থ হ'ল একাধিক থ্রেডগুলি তাদের নিজস্ব কমিটগুলি লেনদেন লগের জন্য একটি লিখন ভাগ করে নিতে পারে, এটি ভাল কারণ এর অর্থ স্থায়ী স্টোরেজটিতে কম সিঙ্ক হয় ।
অন্যদিকে, আপশটটি হ'ল, আপনি সত্যিই মাল্টি-সারি সন্নিবেশ ব্যবহার করতে চান।
এর একটি সীমা রয়েছে যার উপরে এটি পাল্টা উত্পাদনশীল হয়, তবে বেশিরভাগ ক্ষেত্রে এটি কমপক্ষে 10,000 সারি করে। সুতরাং আপনি যদি তাদের 1000 টি সারি পর্যন্ত ব্যাচ করেন তবে আপনি সম্ভবত নিরাপদ।
আপনি যদি মাইএসএএম ব্যবহার করেন তবে পুরোপুরি অন্য কিছু বোঝা রয়েছে, তবে আমি আপনাকে এগুলি থেকে বিরক্ত করব না। শান্তি বর্ষিত হোক।
সাধারণভাবে ডাটাবেসে কম সংখ্যক কল আরও ভাল (যার অর্থ দ্রুত, আরও দক্ষ), সুতরাং সন্নিবেশকে এমনভাবে কোড করার চেষ্টা করুন যাতে এটি ডাটাবেস অ্যাক্সেসকে কমিয়ে দেয়। মনে রাখবেন, আপনি যদি কোনও সংযোগ পুল ব্যবহার না করেন, তবে প্রতিটি ডাটাবেস অ্যাক্সেসের সাথে একটি সংযোগ তৈরি করতে হবে, স্ক্যুয়েল চালানো হবে এবং তারপরে সংযোগটি ছিন্ন করতে হবে। বেশ খানিকটা ওভারহেড!
আপনি চাইবেন:
কত ভাল আপনার সার্ভারে দাঁড়িপাল্লা (তার নিশ্চিতভাবেই ঠিক উপর নির্ভর করে PostgreSQl
, Oracle
এবং MSSQL
), একাধিক থ্রেড এবং একাধিক সংযোগ দিয়ে উপরে জিনিস করে।
সাধারণভাবে, সংযোগের ওভারহেডের কারণে একাধিক সন্নিবেশগুলি ধীর হবে। একসাথে একাধিক সন্নিবেশ করানো হলে প্রতি sertোকানো ওভারহেডের ব্যয় হ্রাস পাবে।
আপনি কোন ভাষাটি ব্যবহার করছেন তার উপর নির্ভর করে আপনি সম্ভবত ডিবিতে যাওয়ার আগে আপনার প্রোগ্রামিং / স্ক্রিপ্টিং ভাষায় একটি ব্যাচ তৈরি করতে পারেন এবং প্রতিটি সন্নিবেশকে ব্যাচে যুক্ত করতে পারেন। তারপরে আপনি একটি সংযোগ অপারেশন ব্যবহার করে একটি বৃহত ব্যাচকে কার্যকর করতে সক্ষম হবেন। জাভাতে এখানে একটি উদাহরণ।
এমওয়াইএসকিউএল 5.5 এক বর্গ স্ক্রোল statementোকানো বিবৃতিটি 300 ডলার থেকে 450 ডলারে নিয়েছে। যখন নীচের পরিসংখ্যানগুলি ইনলাইন একাধিক statোকানো স্ট্যাটেস্টমের জন্য।
(25492 row(s) affected)
Execution Time : 00:00:03:343
Transfer Time : 00:00:00:000
Total Time : 00:00:03:343
আমি বলব ইনলাইনটি যাওয়ার উপায় :)
এটি সন্নিবেশ করার সময় মাইএসকিএল এবং মারিয়াডিবি কীভাবে অনুকূল হয় তা হাস্যকর। আমি মাইএসকিএল 5.7 এবং মারিয়্যাডবি 10.3 পরীক্ষা করেছি, সেগুলিতে কোনও বাস্তব পার্থক্য নেই।
আমি এটি এনভিএমই ডিস্ক, 70,000 আইওপিএস, 1.1 গিগাবাইট / সেকেন্ড সিকো থ্রুটপুট সহ একটি সার্ভারে এটি পরীক্ষা করেছি এবং এটি সম্পূর্ণ ডুপ্লেক্স (পড়ুন এবং লিখুন)।
সার্ভার পাশাপাশি একটি উচ্চ কার্যকারিতা সার্ভার।
এটি 20 গিগাবাইট র্যাম দিয়েছে।
ডাটাবেস সম্পূর্ণ ফাঁকা।
মাল্টি সারি সন্নিবেশ করানোর সময় আমি যে গতিটি পাই তা প্রতি সেকেন্ডে 5000 সন্নিবেশ করানো হয়েছিল (10MB ডেটা অবধি 1MB দিয়ে চেষ্টা করে)
এখন ক্লু:
আমি যদি অন্য থ্রেড যুক্ত করি এবং সেম টেবিলগুলিতে সন্নিবেশ করি তবে হঠাৎ আমার কাছে 2x5000 / সেকেন্ড রয়েছে। আরও একটি থ্রেড এবং আমার 15000 মোট / সেকেন্ড রয়েছে
এটি বিবেচনা করুন: ওয়ান থ্রেড সন্নিবেশ করানো এর অর্থ আপনি ক্রমান্বয়ে ডিস্কে লিখতে পারেন (সূচকগুলি ব্যতীত)। থ্রেড ব্যবহার করার সময় আপনি প্রকৃত সম্ভাব্য পারফরম্যান্সকে হ্রাস করুন কারণ এটি এখন আরও অনেক এলোমেলো অ্যাক্সেস করার প্রয়োজন। তবে রিয়েলিটি চেক শো মাইএসকিএল এত খারাপভাবে অনুকূলিত হয়েছে যে থ্রেডগুলি অনেক সাহায্য করে।
এই জাতীয় সার্ভারের মাধ্যমে সম্ভব প্রকৃত কার্য সম্পাদন সম্ভবত প্রতি সেকেন্ডে কয়েক মিলিয়ন, সিপিইউ নিষ্ক্রিয় ডিস্কটি নিষ্ক্রিয়।
কারণটি পুরোপুরি স্পষ্ট যে মারিয়াদব যেমন মাইএসকিএল অভ্যন্তরীণ বিলম্বিত করে।
id
, parent_id
) মান (1, শূন্য)। পরের মানগুলির মধ্যে একটি সেট এই সারিতে লিঙ্ক করে। যদি আপনি খণ্ডগুলিতে বিভক্ত হন এবং সেই সেটটি অন্য খণ্ডে পরিণত হয়, পুরো প্রক্রিয়াটিকে ব্যর্থ করে এটি প্রথমটির আগে প্রক্রিয়াজাত করা যেতে পারে। কীভাবে মোকাবেলা করার কোনও ধারণা?
একাধিক সন্নিবেশ দ্রুত হয় তবে এটি থ্র্যাশডল করে। অন্য একটি থ্রিক অস্থির করে দিচ্ছে চেকগুলি অস্থায়ীভাবে মেকিং সন্নিবেশগুলি আরও দ্রুত তৈরি করে। আপনার টেবিলে এটি আছে বা না তা বিবেচ্য নয়। উদাহরণস্বরূপ বিদেশী কীগুলি অক্ষম করে পরীক্ষা করুন এবং গতিটি উপভোগ করুন:
SET FOREIGN_KEY_CHECKS=0;
অফকোর্স দ্বারা প্রবেশের পরে এটি আবার চালু করা উচিত:
SET FOREIGN_KEY_CHECKS=1;
বিশাল ডেটা inোকানোর জন্য এটি সাধারণ উপায়। ডেটা ইন্টিগ্রিডিটি ভেঙে যেতে পারে তাই বিদেশী কী চেকগুলি অক্ষম করার আগে আপনি এটির যত্নের সাথে সজাগ করুন।