এই প্রশ্নটি মন্তব্যগুলির একটি পরামর্শের ভিত্তিতে স্ট্যাক ওভারফ্লো থেকে পোস্ট করা হয়েছে , সদৃশটির জন্য ক্ষমা চাই।
প্রশ্নাবলি
প্রশ্ন 1: ডাটাবেস টেবিলের আকারটি বড় হওয়ার সাথে সাথে আমি কীভাবে লসড ডেটা ইনফিল কলটির গতি বাড়াতে মাইএসকিউএল টিউন করতে পারি?
প্রশ্ন 2: কম্পিউটারের একটি ক্লাস্টার ব্যবহার করে বিভিন্ন সিএসভি ফাইল লোড করতে, কর্মক্ষমতাটি উন্নত করতে বা এটি হত্যা করতে হবে? (আগামীকাল লোড ডেটা এবং বাল্ক সন্নিবেশ ব্যবহার করে এটি আমার বেঞ্চ-চিহ্নিতকরণের কাজ)
লক্ষ্য
আমরা চিত্র অনুসন্ধানের জন্য ফিচার ডিটেক্টর এবং ক্লাস্টারিং পরামিতিগুলির বিভিন্ন সংমিশ্রণের চেষ্টা করছি, ফলস্বরূপ আমাদের একটি সময়োপযোগী ফ্যাশনে বড় ডেটাবেস তৈরি করতে সক্ষম হতে হবে।
যন্ত্র তথ্য
মেশিনটিতে 256 জিগ র্যাম রয়েছে এবং সেখানে আরও 2 টি মেশিন একই পরিমাণে র্যামের সাথে পাওয়া যায় যদি ডাটাবেস বিতরণ করে সৃষ্টির সময়ের উন্নতি করার কোনও উপায় থাকে?
টেবিল স্কিমা
টেবিল স্কিমা মত দেখাচ্ছে
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| match_index | int(10) unsigned | NO | PRI | NULL | |
| cluster_index | int(10) unsigned | NO | PRI | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| tfidf | float | NO | | 0 | |
+---------------+------------------+------+-----+---------+----------------+
সঙ্গে তৈরি
CREATE TABLE test
(
match_index INT UNSIGNED NOT NULL,
cluster_index INT UNSIGNED NOT NULL,
id INT NOT NULL AUTO_INCREMENT,
tfidf FLOAT NOT NULL DEFAULT 0,
UNIQUE KEY (id),
PRIMARY KEY(cluster_index,match_index,id)
)engine=innodb;
এখন পর্যন্ত বেঞ্চমার্কিং
প্রথম পদক্ষেপটি ছিল একটি বাইনারি ফাইল থেকে খালি টেবিলের মধ্যে বাল্ক সন্নিবেশ বনাম লোডিংয়ের তুলনা করা।
It took: 0:09:12.394571 to do 4,000 inserts with 5,000 rows per insert
It took: 0:03:11.368320 seconds to load 20,000,000 rows from a csv file
পারফরম্যান্সের পার্থক্য দেখে আমি বাইনারি সিএসভি ফাইল থেকে ডেটা লোড করে চলেছি, প্রথমে নীচে কলটি ব্যবহার করে 100K, 1 এম, 20 এম, 200 এম সারি সম্বলিত বাইনারি ফাইলগুলি লোড করেছি।
LOAD DATA INFILE '/mnt/tests/data.csv' INTO TABLE test;
আমি 2 ঘন্টা পরে 200M সারি বাইনারি ফাইল (GB 3 গিগাবাইট সিএসভি ফাইল) লোড মেরেছি।
সুতরাং আমি টেবিলটি তৈরি করতে একটি স্ক্রিপ্ট চালিয়েছি এবং বাইনারি ফাইল থেকে বিভিন্ন সংখ্যক সারি সন্নিবেশ করলাম তারপর টেবিলটি ড্রপ করুন, নীচের গ্রাফটি দেখুন।
বাইনারি ফাইল থেকে 1M সারি সন্নিবেশ করতে প্রায় 7 সেকেন্ড সময় নিয়েছে। এরপরে আমি স্থির করেছিলাম যে একটি নির্দিষ্ট ডাটাবেসের আকারে কোনও বাধা হয়ে দাঁড়াচ্ছে কিনা তা দেখতে একবারে 1 এম সারি সন্নিবেশ করিয়ে বেঞ্চমার্ক করার সিদ্ধান্ত নিয়েছি। একবার ডেটাবেস প্রায় 59M সারিগুলিতে আঘাত করলে গড় সন্নিবেশের সময়টি প্রায় 5000 / সেকেন্ডে নেমে যায়
গ্লোবাল কী_বফার_সাইজ = 4294967296 সেট করা ছোট বাইনারি ফাইল forোকানোর জন্য গতি কিছুটা উন্নত করেছে। নীচের গ্রাফটি বিভিন্ন সংখ্যক সারির গতি দেখায়
তবে 1 এম সারি প্রবেশের জন্য এটি কার্যকারিতা উন্নত করতে পারেনি।
সারি: 1,000,000 সময়: 0: 04: 13.761428 সন্নিবেশ / সেকেন্ড: 3,940
একটি খালি ডাটাবেস জন্য বনাম
সারি: 1,000,000 সময়: 0: 00: 6.339295 সন্নিবেশ / সেকেন্ড: 315,492
হালনাগাদ
কেবলমাত্র লোড ডেটা কমান্ড ব্যবহার করে নিম্নলিখিত ক্রম ব্যবহার করে লোড ডেটা করা
SET autocommit=0;
SET foreign_key_checks=0;
SET unique_checks=0;
LOAD DATA INFILE '/mnt/imagesearch/tests/eggs.csv' INTO TABLE test_ClusterMatches;
SET foreign_key_checks=1;
SET unique_checks=1;
COMMIT;
সুতরাং এটি উত্পন্ন হচ্ছে এমন ডাটাবেস আকারের দিক থেকে বেশ প্রতিশ্রুতিবদ্ধ দেখায় তবে অন্যান্য সেটিংস লোড ডেটা ইনফিল কলটির কার্যকারিতা প্রভাবিত করে না বলে মনে হয়।
আমি তখন বিভিন্ন মেশিন থেকে একাধিক ফাইল লোড করার চেষ্টা করেছিলাম কিন্তু লোড ডেটা ইনফিল কমান্ডটি অন্য মেশিনগুলির সাথে সময় শেষ হওয়ার কারণে বড় আকারের ফাইলের কারণে টেবিলটি লক করে দেয়
ERROR 1205 (HY000) at line 1: Lock wait timeout exceeded; try restarting transaction
বাইনারি ফাইলে সারি সংখ্যা বাড়ানো
rows: 10,000,000 seconds rows: 0:01:36.545094 inserts/sec: 103578.541236
rows: 20,000,000 seconds rows: 0:03:14.230782 inserts/sec: 102970.29026
rows: 30,000,000 seconds rows: 0:05:07.792266 inserts/sec: 97468.3359978
rows: 40,000,000 seconds rows: 0:06:53.465898 inserts/sec: 96743.1659866
rows: 50,000,000 seconds rows: 0:08:48.721011 inserts/sec: 94567.8324859
rows: 60,000,000 seconds rows: 0:10:32.888930 inserts/sec: 94803.3646283
সমাধান: স্বতঃবৃদ্ধি ব্যবহারের পরিবর্তে মাইএসকিউএল এর বাইরে আইডি প্রিকম্পুটিং ing
সঙ্গে টেবিল নির্মাণ
CREATE TABLE test (
match_index INT UNSIGNED NOT NULL,
cluster_index INT UNSIGNED NOT NULL,
id INT NOT NULL ,
tfidf FLOAT NOT NULL DEFAULT 0,
PRIMARY KEY(cluster_index,match_index,id)
)engine=innodb;
এসকিউএল সহ
LOAD DATA INFILE '/mnt/tests/data.csv' INTO TABLE test FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';"
সূচিগুলিকে প্রাক-গণনা করতে স্ক্রিপ্টটি পাওয়া ডাটাবেস আকারে বাড়ার সাথে সাথে পারফরম্যান্স হিট সরিয়ে ফেলেছে বলে মনে হয়।
আপডেট 2 - মেমরি টেবিল ব্যবহার করে
ইন-মেমরি টেবিলটি ডিস্ক-ভিত্তিক টেবিলের দিকে নিয়ে যাওয়ার ব্যয়কে বিবেচনায় না নিয়ে মোটামুটিভাবে 3 গুণ বেশি দ্রুত।
rows: 0 seconds rows: 0:00:26.661321 inserts/sec: 375075.18851
rows: 10000000 time: 0:00:32.765095 inserts/sec: 305202.83857
rows: 20000000 time: 0:00:38.937946 inserts/sec: 256818.888187
rows: 30000000 time: 0:00:35.170084 inserts/sec: 284332.559456
rows: 40000000 time: 0:00:33.371274 inserts/sec: 299658.922222
rows: 50000000 time: 0:00:39.396904 inserts/sec: 253827.051994
rows: 60000000 time: 0:00:37.719409 inserts/sec: 265115.500617
rows: 70000000 time: 0:00:32.993904 inserts/sec: 303086.291334
rows: 80000000 time: 0:00:33.818471 inserts/sec: 295696.396209
rows: 90000000 time: 0:00:33.534934 inserts/sec: 298196.501594
একটি মেমরি ভিত্তিক টেবিলের মধ্যে ডেটা লোড এবং তারপর একটি ডিস্ক ভিত্তিক টেবিলে এটা অনুলিপি করে অংশ 10 মিনিট 59,71 সেকেন্ড একজন ওভারহেড ক্যোয়ারী দিয়ে 107.356.741 সারি অনুলিপি করতে ছিল
insert into test Select * from test2;
যা এটি 100M সারি লোড করতে আনুমানিক 15 মিনিট করে তোলে, এটি প্রায়শই এটি সরাসরি একটি ডিস্ক ভিত্তিক টেবিলের মধ্যে asোকানোর সমান।
id
দ্রুত পরিবর্তন করা উচিত। (যদিও আমি মনে করি আপনি এটি সন্ধান করছেন না)