अधिकांश तालिका के लिए InnoDB भंडारण इंजन के साथ MySQL 5.6 का उपयोग करना। InnoDB बफर पूल का आकार 15 GB है और Innodb DB + अनुक्रमित लगभग 10 GB हैं। सर्वर में 32GB रैम है और यह Cent OS 7 x64 चला रहा है।
मेरे पास एक बड़ी तालिका है जिसमें लगभग 10 लाखों + रिकॉर्ड हैं।
मुझे हर 24 घंटे में एक रिमोट सर्वर से अपडेट डंप फ़ाइल मिलती है। फ़ाइल सीएसवी प्रारूप में है। मेरा उस प्रारूप पर नियंत्रण नहीं है। फ़ाइल ~ 750 एमबी है। मैंने एक MyISAM तालिका पंक्ति में पंक्ति द्वारा डेटा डालने की कोशिश की और इसमें 35 मिनट लगे।
मुझे फ़ाइल से 10-12 में से प्रति पंक्ति केवल 3 मान लेने और डेटाबेस में इसे अपडेट करने की आवश्यकता है।
इस तरह से कुछ हासिल करने का सबसे अच्छा तरीका क्या है?
मुझे रोजाना ऐसा करने की जरूरत है।
वर्तमान में प्रवाह इस तरह है:
- mysqli_begin_transaction
- डंप फ़ाइल लाइन लाइन द्वारा पढ़ें
- लाइन द्वारा प्रत्येक रिकॉर्ड लाइन को अपडेट करें।
- mysqli_commit
ऊपर के संचालन को पूरा होने में लगभग 30-40 मिनट लगते हैं और इसे करते समय, अन्य अपडेट होते रहते हैं जो मुझे देता है
लॉक प्रतीक्षा समय समाप्त हो गया; लेनदेन को पुनः आरंभ करने का प्रयास करें
अपडेट १
उपयोग कर नई तालिका में डेटा लोड हो रहा है LOAD DATA LOCAL INFILE
। MyISAM में इसे 38.93 sec
जबकि InnoDB में 7 मिनट 5.21 सेकंड लगे। फिर मैंने किया:
UPDATE table1 t1, table2 t2
SET
t1.field1 = t2.field1,
t1.field2 = t2.field2,
t1.field3 = t2.field3
WHERE t1.field10 = t2.field10
Query OK, 434914 rows affected (22 hours 14 min 47.55 sec)
अपडेट २
ज्वाइन क्वेरी के साथ एक ही अपडेट
UPDATE table1 a JOIN table2 b
ON a.field1 = b.field1
SET
a.field2 = b.field2,
a.field3 = b.field3,
a.field4 = b.field4
(14 hours 56 min 46.85 sec)
टिप्पणियों में प्रश्नों से स्पष्टीकरण:
- तालिका में लगभग 6% पंक्तियों को फ़ाइल द्वारा अपडेट किया जाएगा, लेकिन कभी-कभी यह 25% तक हो सकती है।
- अद्यतन किए जा रहे क्षेत्रों पर अनुक्रमणिकाएँ हैं। टेबल पर 12 इंडेक्स हैं, और 8 इंडेक्स में अपडेट फ़ील्ड शामिल हैं।
- एक लेन-देन में अद्यतन करना आवश्यक नहीं है । इसमें समय लग सकता है लेकिन 24 घंटे से अधिक नहीं। मैं इसे पूरी तालिका को लॉक किए बिना 1 घंटे में प्राप्त करना चाहता हूं, क्योंकि बाद में मुझे स्फिंक्स इंडेक्स को अपडेट करना होगा जो इस तालिका पर निर्भर है। इससे कोई फर्क नहीं पड़ता कि चरण तब तक लंबी अवधि लेते हैं जब तक डेटाबेस अन्य कार्यों के लिए उपलब्ध है।
- मैं प्रीप्रोसेस चरण में सीएसवी प्रारूप को संशोधित कर सकता हूं। केवल एक चीज जो मायने रखती है वह है त्वरित अपडेट और बिना लॉकिंग।
- तालिका 2 MyISAM है। यह लोड डेटा इन्फाइल का उपयोग करके सीएसवी फ़ाइल से नव निर्मित तालिका है। MYI फ़ाइल का आकार 452 एमबी है। तालिका 2 को फ़ील्ड 1 कॉलम पर अनुक्रमित किया गया है।
- MyISAM तालिका का MYD 663MB है।
अपडेट 3:
यहाँ दोनों तालिका के बारे में अधिक जानकारी दी गई है।
CREATE TABLE `content` (
`hash` char(40) CHARACTER SET ascii NOT NULL DEFAULT '',
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`og_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`keywords` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`files_count` smallint(5) unsigned NOT NULL DEFAULT '0',
`more_files` smallint(5) unsigned NOT NULL DEFAULT '0',
`files` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`category` smallint(3) unsigned NOT NULL DEFAULT '600',
`size` bigint(19) unsigned NOT NULL DEFAULT '0',
`downloaders` int(11) NOT NULL DEFAULT '0',
`completed` int(11) NOT NULL DEFAULT '0',
`uploaders` int(11) NOT NULL DEFAULT '0',
`creation_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`upload_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`last_updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`vote_up` int(11) unsigned NOT NULL DEFAULT '0',
`vote_down` int(11) unsigned NOT NULL DEFAULT '0',
`comments_count` int(11) NOT NULL DEFAULT '0',
`imdb` int(8) unsigned NOT NULL DEFAULT '0',
`video_sample` tinyint(1) NOT NULL DEFAULT '0',
`video_quality` tinyint(2) NOT NULL DEFAULT '0',
`audio_lang` varchar(127) CHARACTER SET ascii NOT NULL DEFAULT '',
`subtitle_lang` varchar(127) CHARACTER SET ascii NOT NULL DEFAULT '',
`verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
`uploader` int(11) unsigned NOT NULL DEFAULT '0',
`anonymous` tinyint(1) NOT NULL DEFAULT '0',
`enabled` tinyint(1) unsigned NOT NULL DEFAULT '0',
`tfile_size` int(11) unsigned NOT NULL DEFAULT '0',
`scrape_source` tinyint(1) unsigned NOT NULL DEFAULT '0',
`record_num` int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`record_num`),
UNIQUE KEY `hash` (`hash`),
KEY `uploaders` (`uploaders`),
KEY `tfile_size` (`tfile_size`),
KEY `enabled_category_upload_date_verified_` (`enabled`,`category`,`upload_date`,`verified`),
KEY `enabled_upload_date_verified_` (`enabled`,`upload_date`,`verified`),
KEY `enabled_category_verified_` (`enabled`,`category`,`verified`),
KEY `enabled_verified_` (`enabled`,`verified`),
KEY `enabled_uploader_` (`enabled`,`uploader`),
KEY `anonymous_uploader_` (`anonymous`,`uploader`),
KEY `enabled_uploaders_upload_date_` (`enabled`,`uploaders`,`upload_date`),
KEY `enabled_verified_category` (`enabled`,`verified`,`category`),
KEY `verified_enabled_category` (`verified`,`enabled`,`category`)
) ENGINE=InnoDB AUTO_INCREMENT=7551163 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED
CREATE TABLE `content_csv_dump_temp` (
`hash` char(40) CHARACTER SET ascii NOT NULL DEFAULT '',
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`category_id` int(11) unsigned NOT NULL DEFAULT '0',
`uploaders` int(11) unsigned NOT NULL DEFAULT '0',
`downloaders` int(11) unsigned NOT NULL DEFAULT '0',
`verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`hash`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
और यहां अपडेट क्वेरी है जो content
डेटा का उपयोग करके तालिका अपडेट करती हैcontent_csv_dump_temp
UPDATE content a JOIN content_csv_dump_temp b
ON a.hash = b.hash
SET
a.uploaders = b.uploaders,
a.downloaders = b.downloaders,
a.verified = b.verified
अद्यतन 4:
उपरोक्त सभी परीक्षण परीक्षण मशीन पर किए गए थे। लेकिन अब मैंने उत्पादन मशीन पर एक ही परीक्षण किया, और प्रश्न बहुत तेज हैं।
mysql> UPDATE content_test a JOIN content_csv_dump_temp b
-> ON a.hash = b.hash
-> SET
-> a.uploaders = b.uploaders,
-> a.downloaders = b.downloaders,
-> a.verified = b.verified;
Query OK, 2673528 rows affected (7 min 50.42 sec)
Rows matched: 7044818 Changed: 2673528 Warnings: 0
मुझे अपनी गलती के लिए क्षमा चाहिए। प्रत्येक रिकॉर्ड अद्यतन के बजाय जुड़ने का उपयोग करना बेहतर है। अब मैं rick_james द्वारा सुझाए गए इंडेक्स का उपयोग करके mpre को बेहतर बनाने की कोशिश कर रहा हूं, बेंच-मार्किंग हो जाने के बाद अपडेट हो जाएगा।
UPDATEs
। कृपया हमें बताएं कि वास्तव में क्या सीधा बयान दिखता csv डेटा से तालिका अद्यतन करने के लिए पसंद करते हैं। फिर हम आपकी आवश्यकताओं को पूरा करने वाली तकनीक को तैयार करने में आपकी सहायता करने में सक्षम हो सकते हैं।
update
, और कृपया अद्यतन प्रश्न की जाँच करें। धन्यवाद
INDEX(field2, field3, field4)
(किसी भी क्रम में) है? कृपया हमें दिखाओSHOW CREATE TABLE
।