2011-09-13 8 views
7

मैं अपनी तालिका से लाखों रिकॉर्ड (आकार लगभग 30 जीबी) संसाधित करने की कोशिश कर रहा हूं और मैं वर्तमान में इसे पेजिंग (mysql 5.1.36) का उपयोग कर कर रहा हूं। मेरे लूप में उपयोग की जाने वाली क्वेरीपेजिंग के साथ बड़ी संख्या में डेटाबेस प्रविष्टियों को संसाधित करना

select blobCol from large_table 
where name= 'someKey' and city= 'otherKey' 
order by name 
LIMIT <pageNumber*pageSize>, <pageSize> 

यह लगभग 500 के रिकॉर्ड के लिए बिल्कुल ठीक काम करता है। मेरे पास 5000 का पेज आकार है जिसका मैं उपयोग कर रहा हूं और पेज 100 के बाद, क्वेरी नाटकीय रूप से धीमा हो रही है। पहले ~ 80 पृष्ठों को 2-3 सेकंड में निकाला जाता है लेकिन पृष्ठ 130 के बाद, प्रत्येक पृष्ठ को कम से कम 30 सेकंड तक पुनर्प्राप्त करने के लिए लगभग 30 सेकंड लगते हैं। मेरे प्रश्नों में से एक के बारे में 900 पृष्ठ हैं और इसमें बहुत अधिक समय लगेगा।

The table structure is (type is MyISAM) 
    name char(11) 
    id int // col1 & col2 is a composite key 
    city varchar(80) // indexed 
    blobCol longblob 

मैं इसे गति देने के लिए क्या कर सकता हूं? क्वेरी के लिए समझाने से पता चलता इस

select_type: SIMPLE 
possible_keys: city 
key : city 
type: ref 
key_len: 242 
ref: const 
rows: 4293720 
Extra: using where; using filesort 

मामले में यह अपने सर्वर (24 जीबी राम, 2 क्वाड-कोर procs) के लिए मदद करता है, my.cnf इन प्रविष्टियों

key_buffer_size = 6144M 
    max_connections = 20 
    max_allowed_packet = 32M 
    table_open_cache = 1024 
    sort_buffer_size = 256M 
    read_buffer_size = 128M 
    read_rnd_buffer_size = 512M 
    myisam_sort_buffer_size = 128M 
    thread_cache_size = 16 
    tmp_table_size = 128M 
    max_heap_table_size = 64M 
+0

मैं हाइबरनेट (अनुमानों) में देखो सुझाव है कि [http://docs.jboss.org/hibernate/ कोर/3.3/संदर्भ/एन/एचटीएमएल/querycriteria.html # querycriteria-projection]। इसे एसओ पर भी पाया गया है जो अनुमानों का उपयोग नहीं करता है http://stackoverflow.com/questions/168084/is-there-a-more- कुशल -वे-ऑफ-मेकिंग-पेजिनेशन-इन-हाइबरनेट-से-एक्जिक्यूटिंग-से – Shahzeb

+0

मैं इसे createSQLQuery एपीआई के माध्यम से चला रहा हूं, createQuery नहीं जो हाइबरेट इकाइयों का उपयोग करता है। मैंने createCriteria विधियों का उपयोग करने का प्रयास किया और इससे मेरा जेवीएम मेमोरी अपवादों से बाहर निकल गया क्योंकि यह स्मृति में सभी डेटा को रख रहा था। यह कम से कम काम करता है, यद्यपि थोड़ा सा धीमा है – randomThought

उत्तर

2

यहाँ मैं क्या किया, और 10

मुझे अपने मूल प्रश्न के निष्पादन योजना के रूप में महसूस किया का एक पहलू से कुल निष्पादन समय कम हो गया था कि यह सब परिणाम छंटाई और अनदेखी के लिए filesort उपयोग कर रहा था है अनुक्रमित। यह एक कचरा है।

मेरा परीक्षण डेटाबेस: 5 एम रिकॉर्ड, 20 जीबी आकार। तालिका संरचना जैसा कि

सीधे पहली क्वेरी में ब्लॉबकॉल प्राप्त करने के बजाय, मुझे पहले प्रत्येक पृष्ठ की शुरुआत के लिए 'नाम' का मान मिलता है। इस क्वेरी को अनिश्चित काल तक चलाएं जब तक कि यह 0 परिणाम न लौटाए। हर बार, एक सूची

SELECT name 
FROM my_table 
where id = <anyId> // I use the id column for partitioning so I need this here 
order by name 
limit <pageSize * pageNumber>, 1 

साइन पृष्ठ संख्या पहले से ज्ञात नहीं है, परिणाम जोड़ने के लिए, मान 0 के साथ शुरू और जब तक क्वेरी अशक्त रिटर्न बढ़ाने रखने के लिए। आप एक चुनिंदा गिनती भी कर सकते हैं (*) लेकिन वह स्वयं अधिक समय ले सकता है और कुछ भी अनुकूलित करने में मदद नहीं करेगा। पृष्ठ संख्या 60 से अधिक हो जाने के बाद प्रत्येक क्वेरी को चलाने के लिए लगभग 2 सेकंड लगते हैं।

मेरे लिए, पृष्ठ का आकार 5000 था इसलिए मुझे स्थिति 0, 5001, 10001, 15001 और इसी तरह 'नाम' तारों की एक सूची मिली।पृष्ठों की संख्या 1000 हो गई है और स्मृति में 1000 परिणामों की एक सूची संग्रहीत करना महंगा नहीं है।

अब, सूची के माध्यम से पुनरावृति और इस क्वेरी

SELECT blobCol 
FROM my_table 
where name >= <pageHeader> 
and name < <nextPageHeader> 
and city="<any string>" 
and id= 1 

इस एन बार चलाया जाएगा, जहां पहले से प्राप्त एन = सूची का आकार चलाते हैं। चूंकि 'नाम' प्राथमिक कुंजी कर्नल है, और 'शहर' को भी अनुक्रमित किया गया है, एक्सप्लाइन दिखाता है कि यह गणना इंडेक्स का उपयोग करके स्मृति में किया जाता है।

अब, प्रत्येक क्वेरी को मूल 30-40 की बजाय चलाने के लिए 1 सेकंड लगते हैं। तो प्रति पृष्ठ 2 सेकंड के प्री-प्रोसेसिंग समय को संयोजित करते हुए, प्रति पृष्ठ कुल समय 30-40 के बजाय 3-4 सेकंड होता है।

किसी को भी एक बेहतर समाधान है या यदि वहाँ कुछ इस एक साथ चमक से गलत है, तो कृपया मुझे बताएं तो

0

आप कर सकते हैं नहीं है अपने अधिक सटीक पूछताछ करें ताकि सीमा कम हो।

SELECT col1,col2, col4 
FROM large_table 
WHERE col1>"SomeKey" OR 
(col1="SomeKey" AND col2>="OtherKey") 
ORDER BY col1,col2 
LIMIT PageSize 

लेकिन प्रत्येक डेटाबेस कॉल के बाद "कुछकी" और "अन्यकी" अपडेट करें।

+0

"सीमा कम है" से आपका क्या मतलब है? और मुझे कोल् 3 के साथ परिणाम पूछने की ज़रूरत है, जो अनुक्रमित है, लेकिन प्राथमिक कुंजी में से एक नहीं है। यह इच्छित स्ट्रिंग से अधिक मिलान नहीं करेगा और यह सिर्फ = डालने से बेहतर कैसे होगा? – randomThought

+0

जहां आप LIMIT <पृष्ठ संख्या * पृष्ठ आकार> के बजाय LIMIT पृष्ठ आकार का उपयोग करते हैं, क्योंकि प्रत्येक बार जब आप आईडी छोड़ देते हैं तो आपने छोड़ा था। इस मामले में आप 2 मान पास करते हैं क्योंकि आपकी टिप्पणी कहती है कि यह 2 कॉलम समग्र कुंजी है। मुझे लगता है कि यह प्राथमिक कुंजी पर क्लस्टर्ड इंडेक्स है और हालांकि इसे धोया नहीं गया है। यदि इसे धोया गया है तो आपको शहर> 'somecity' या (शहर = 'somecity' और col1> 'someKey) या (शहर =' somecity 'और col1 =' someKey 'और col2>' अन्यकी ') करना है। यदि आपके पास प्रत्येक पृष्ठ के लिए 'कुछता', 'कुछकी' और 'अन्यकी' के नए मानों को पारित करने की क्षमता है, तो यह बहुत तेज़ होना चाहिए। – psr

0

मैंने अतीत में ओरेकल 10 जी डेटाबेस के साथ ऐसा करने की कोशिश की है और उसी परिणाम (मेरी तालिका में 60 मिलियन पंक्तियां थीं)। पहले पृष्ठ जल्दी से पुनर्प्राप्त किए गए थे लेकिन पृष्ठ संख्या में वृद्धि के साथ, क्वेरी बहुत धीमी हो गई। इंडेक्स के साथ आप बहुत कुछ नहीं देख सकते हैं क्योंकि वे सही दिखते हैं और मुझे यकीन नहीं है कि आप डेटाबेस कॉन्फ़िगरेशन को ट्यून करके क्या हासिल कर सकते हैं। मुझे लगता है कि मेरे पास अलग-अलग आवश्यकताएं थीं, लेकिन मुझे मिला एकमात्र समाधान फाइलों को डेटा डंप करना था। यदि आपके पास col1 के लिए मानों का सीमित सेट है, तो आप col1 से छुटकारा पा सकते हैं और एन टेबल उत्पन्न कर सकते हैं, एक को col1 के प्रत्येक ज्ञात मान के लिए। अगर col1 अज्ञात है, तो मुझे इसका समाधान नहीं पता है। आप बहुत बड़ी टेबल से डेटा के छोटे सेट पुनर्प्राप्त कर सकते हैं, लेकिन डेटा के बड़े सेट को पुनर्प्राप्त करने में काफी समय लगता है और पेजिनेशन आपकी मदद नहीं करता है। आपको फ़ाइलों को डंप करने या विभाजन डेटा में अन्य तालिकाओं को उत्पन्न करके प्रीप्रोसेस करना होगा।

+0

दुर्भाग्य से इस रिकॉर्डसेट के लिए प्रत्येक col1 मान अद्वितीय है। तालिका int col2 कॉलम (~ 20 विभाजन) पर विभाजित है। प्रत्येक विभाजन में, अद्वितीय में col1 कॉलम। मैंने अभी तक 1 विभाजन के साथ इसका परीक्षण किया है। मुझे यकीन नहीं है कि प्रदर्शन के बाद क्या हो रहा है जब एक बार अन्य विभाजन भरने लगते हैं। – randomThought

+0

mysql में ऑप्टिमाइज़ेशन द्वारा ऑर्डर किया गया है, लेकिन अगर वे मेरे मामले में चाबियाँ और ऑर्डर अलग हैं तो वे काम नहीं करते हैं। – randomThought

+0

हाँ, जो भी समाधान आप पाते हैं, कुंजी किसी भी तरह से प्रीप्रोकैसिंग समय बिताना है। यह आसान दिखता है लेकिन यह बिल्कुल नहीं है। – martincho

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