2010-09-09 19 views
13

पर प्रदर्शन घटता है मैं एक विशाल तालिका के साथ काम कर रहा हूं जिसमें 250 + मिलियन पंक्तियां हैं। स्कीमा सरल है।MySQL डालने प्रदर्शन एक बड़ी तालिका

CREATE TABLE MyTable (
     id BIGINT PRIMARY KEY AUTO_INCREMENT, 
     oid INT NOT NULL, 
     long1 BIGINT NOT NULL, 
     str1 VARCHAR(30) DEFAULT NULL, 
     str2 VARCHAR(30) DEFAULT NULL, 
     str2 VARCHAR(200) DEFAULT NULL, 
     str4 VARCHAR(50) DEFAULT NULL, 
     int1 INT(6) DEFAULT NULL, 
     str5 VARCHAR(300) DEFAULT NULL, 
     date1 DATE DEFAULT NULL, 
     date2 DATE DEFAULT NULL, 
     lastUpdated TIMESTAMP NOT NULL, 
     hashcode INT NOT NULL, 
     active TINYINT(1) DEFAULT 1, 
     KEY oid(oid), 
     KEY lastUpdated(lastUpdated), 
     UNIQUE KEY (hashcode, active), 
     KEY (active) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 MAX_ROWS=1000000000; 

सम्मिलन का प्रदर्शन उल्लेखनीय रूप से गिरा दिया गया है। तालिका में 150 मिलियन पंक्तियों तक, इसमें 10,000 पंक्तियों को डालने के लिए 5-6 सेकंड लगते थे। अब यह 2-4 बार बढ़ गया है। Innodb की ibdata फ़ाइल 107 जीबी तक बढ़ी है। इनोडब कॉन्फ़िगरेशन पैरामीटर निम्नानुसार हैं।

innodb_buffer_pool_size = 36G # Machine has 48G memory 
innodb_additional_mem_pool_size = 20M 
innodb_data_file_path = ibdata1:10M:autoextend 
innodb_log_file_size = 50M 
innodb_log_buffer_size = 20M 
innodb_log_files_in_group=2 
innodb_flush_log_at_trx_commit = 1 
innodb_lock_wait_timeout = 50 
innodb_thread_concurrency = 8 
innodb_flush_method = O_DIRECT 
expire_logs_days = 4 

आईओ प्रतीक्षा समय बढ़ गया है जैसा कि top के साथ देखा गया है। मैंने O_DSYNC को फ्लश विधि बदलने की कोशिश की है, लेकिन इससे मदद नहीं मिली। डिस्क हार्डवेयर RAID 10 सेटअप से बना है। एकल डिस्क के साथ पहले के सेटअप में, आईओ कोई समस्या नहीं थी।

तालिका केवल विभाजन का विभाजन कर रहा है? एकल 100 जी फ़ाइल को "छोटी" फाइलों में विभाजित करने में मदद मिल सकती है? क्या कोई चर है जिसे RAID के लिए ट्यून करने की आवश्यकता है?

अद्यतन: यह एक परीक्षण प्रणाली है। मुझे कोई बदलाव करने की स्वतंत्रता है।

उत्तर

13

आपने यह नहीं कहा कि यह एक परीक्षण प्रणाली या उत्पादन था; मुझे लगता है कि यह उत्पादन है।

यह संभावना है कि आपको एक आकार में तालिका मिल गई है जहां इसकी अनुक्रमणिका (या पूरी लॉट) अब स्मृति में फिट नहीं है।

इसका मतलब है कि इनओडीबी को आवेषण के दौरान पृष्ठों को पढ़ना होगा (आपकी नई पंक्तियों के सूचकांक मानों के वितरण के आधार पर)। पृष्ठों को पढ़ना (यादृच्छिक पढ़ता है) वास्तव में धीमा है और यदि संभव हो तो इससे बचा जाना चाहिए।

विभाजन सबसे स्पष्ट समाधान की तरह लगता है, लेकिन MySQL का विभाजन आपके उपयोग-मामले में फिट नहीं हो सकता है।

आपको निश्चित रूप से सभी संभावित विकल्पों पर विचार करना चाहिए - यह देखने के लिए कि यह कैसा व्यवहार करता है, अपनी प्रयोगशाला में एक टेस्ट सर्वर पर टेबल प्राप्त करें।

आपकी प्राथमिक कुंजी मुझे देखती है जैसे कि यह संभवतः आवश्यक नहीं है (आपके पास एक और अद्वितीय इंडेक्स है), इसलिए इसे समाप्त करना एक विकल्प है।

भी innodb प्लगइन और संपीड़न पर विचार करें, यह आपके innodb_buffer_pool आगे बढ़ जाएगा।

आपको वास्तव में यह निर्णय लेने के लिए अपने उपयोग-मामलों का विश्लेषण करने की आवश्यकता है कि आपको वास्तव में यह सब डेटा रखने की आवश्यकता है, और क्या विभाजन एक समझदार समाधान है।

इस एप्लिकेशन पर कोई भी बदलाव करने से आपके उपयोगकर्ताओं के लिए नई प्रदर्शन समस्याएं पेश होने की संभावना है, इसलिए आप यहां वास्तव में सावधान रहना चाहते हैं। यदि आपको सम्मिलित प्रदर्शन में सुधार करने का कोई तरीका मिलता है, तो यह संभव है कि इससे खोज प्रदर्शन या अन्य परिचालनों के प्रदर्शन को कम किया जा सके। इस तरह के बदलाव को जारी करने से पहले आपको उत्पादन-ग्रेड हार्डवेयर पर पूरी तरह से प्रदर्शन परीक्षण करने की आवश्यकता होगी।

+1

धन्यवाद, मार्क। यह एक परीक्षण प्रणाली है। –

+0

सूचकांक आकार के बारे में आपकी युक्ति सहायक है। मैं अनुक्रमण पर काम कर रहा हूं। –

2

जैसा कि मार्कआर ने ऊपर टिप्पणी की है, जब प्रदर्शन आपके बफर पूल में फिट नहीं हो सकता है तो प्रदर्शन खराब हो जाता है। इनो डीबी में एक यादृच्छिक आईओ कमी प्रणाली है (जिसे सम्मिलित बफर कहा जाता है) जो इस समस्या में से कुछ को रोकता है - लेकिन यह आपके अद्वितीय सूचकांक पर काम नहीं करेगा। प्रत्येक डालने पर इंडेक्स (हैशकोड, सक्रिय) पर जांच की जानी चाहिए सुनिश्चित करें कि कोई डुप्लिकेट प्रविष्टियां डाली नहीं गई हैं। यदि हैशकोड प्राथमिक कुंजी का पालन नहीं करता है, तो यह जांच यादृच्छिक IO हो सकती है।

क्या आपके पास स्कीमा बदलने की संभावना है?

आपका सबसे अच्छा शर्त के लिए है:

(क) (, इस अपने आप में मदद मिलेगी के बाद से यादृच्छिक पढ़ने कम हो जाएगा) hashCode कोई अनुक्रमिक, या प्रकार थोक डालने से पहले hashCode द्वारा बनाओ।

(बी) प्राथमिक कुंजी बनाएं (हैशकोड, सक्रिय) - क्रमबद्ध क्रम में डेटा डालें। मैं अनुमान लगा रहा हूं कि आपका एप्लिकेशन शायद हैशकोड द्वारा पढ़ता है - और एक प्राथमिक कुंजी लुकअप तेज़ है।

4

इनोडब के साथ अपने अनुभव से यह गहन सिस्टम लिखने की सीमा को प्रभावित करता है भले ही आपके पास वास्तव में अनुकूलित डिस्क उपप्रणाली है। मुझे आश्चर्य है कि आप इसे 100 जीबी तक पहुंचने में कामयाब रहे।

यह ट्विटर कुछ समय पहले मारा गया था और महसूस किया कि इसे shard करने की आवश्यकता है - http://github.com/twitter/gizzard देखें।

यह सब अपने उपयोग के मामलों पर निर्भर करता है लेकिन आप यह भी कैसेंड्रा के लिए mysql से स्थानांतरित कर सकता है यह लिखने गहन अनुप्रयोगों के लिए वास्तव में अच्छा प्रदर्शन के रूप में। (Http://cassandra.apache.org)

1

आप का उल्लेख नहीं था आपका वर्कलोड कैसा है, लेकिन यदि बहुत सारे पढ़े नहीं हैं या आपके पास पर्याप्त मुख्य-मेमोरी है, तो दूसरा विकल्प है कि माईएसक्यूएल के लिए एक लिखने-अनुकूलित बैकएंड का उपयोग करना है। Tokutek डेटासेट बढ़ने के रूप में 18x तेज आवेषण और एक और अधिक फ्लैट प्रदर्शन वक्र दावा करता है।

tokutek.com

http://tokutek.com/downloads/tokudb-performance-brief.pdf

0

मैं हूँ दूसरा @ अनुक्रमित कम करने के बारे MarkR की टिप्पणी। एक और चीज जो आपको देखना चाहिए वह आपके innodb_log_file_size को बढ़ा रहा है। यह दुर्घटना वसूली का समय बढ़ाता है, लेकिन मदद करनी चाहिए। सावधान रहें कि आपको सर्वर को पुनरारंभ करने से पहले पुरानी फ़ाइलों को निकालने की आवश्यकता है।

जनरल InnoDB ट्यूनिंग टिप्स: http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/

तुम भी आवेषण करने के लिए LOAD DATA INFILE के बारे में पता होना चाहिए। यह बहुत तेज है। अगर आप 1 सेकंड डेटा हानि सहन

innodb_log_file_size = 50M से
0

बढ़ाएँ innodb_log_file_size = 500M

और innodb_flush_log_at_trx_commit करने के लिए 0 होना चाहिए।

संबंधित मुद्दे