2010-04-06 15 views
5

मेरे पास एक सारणी है जो तृतीय पक्ष वेबसाइटों पर विज़िटर सत्रों के बारे में कुछ बुनियादी डेटा संग्रहीत करती है। यह इसकी संरचना है:एकाधिक इंडेक्स वाले तालिका के लिए mysql अनुक्रमणिका ऑप्टिमाइज़ेशन जो कुछ कॉलमों को इंडेक्स करता है

id, site_id, unixtime, unixtime_last, ip_address, uid 

चार अनुक्रमित रहे हैं: id, site_id/unixtime, site_id/ip_address, और site_id/uid

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

स्पष्ट रूप से 3 इंडेक्स के अंदर साइट_आईडी को संग्रहीत करना लिखने की गति और भंडारण दोनों के लिए अक्षम है, लेकिन मुझे इसके चारों ओर कोई रास्ता नहीं दिख रहा है, क्योंकि मुझे किसी दिए गए विशिष्ट साइट_आईडी के लिए इस डेटा को तुरंत पूछने में सक्षम होना चाहिए।

इसे और अधिक कुशल बनाने पर कोई विचार?

मुझे कुछ बहुत ही बुनियादी चीजों के अलावा बी-पेड़ वास्तव में समझ में नहीं आता है, लेकिन यह अधिक कुशल है कि सूचकांक का बायां सबसे अधिक स्तंभ कम से कम भिन्नता वाला है - सही? क्योंकि मैंने साइट_आईडी को ip_address और uid दोनों के लिए इंडेक्स का दूसरा कॉलम माना है, लेकिन मुझे लगता है कि सूचकांक कम कुशल होगा क्योंकि आईपी और यूआईडी साइट आईडी से अधिक भिन्न होने जा रहे हैं, क्योंकि हमारे पास केवल 8000 है डेटाबेस सर्वर प्रति अद्वितीय साइटें, लेकिन दैनिक आधार पर सभी ~ 8000 साइटों में लाखों अद्वितीय विज़िटर।

मैंने आईपी और यूआईडी इंडेक्स से साइट_आईडी को पूरी तरह से हटाने पर भी विचार किया है, क्योंकि उसी विज़िटर की संभावनाएं एक ही डेटाबेस सर्वर को साझा करने वाली कई साइटों पर जा रही हैं, लेकिन ऐसे मामलों में जहां यह होता है, मुझे डर है यह निर्धारित करने में काफी धीमा हो सकता है कि यह इस साइट_आईडी के लिए एक नया आगंतुक है या नहीं। क्वेरी होगा कुछ की तरह:

select id from sessions where uid = 'value' and site_id = 123 limit 1 

... इसलिए यदि इस आगंतुक से पहले इस साइट का दौरा किया था, तो यह किसी बंद कर दिया इस site_id साथ एक पंक्ति को खोजने के लिए की आवश्यकता होगी। यह जरूरी अति तेज़ नहीं होगा, लेकिन स्वीकार्य रूप से तेज़ होगा। लेकिन कहें कि हमारे पास ऐसी साइट है जो दिन में 500,000 आगंतुकों को प्राप्त करती है, और एक विशेष आगंतुक इस साइट से प्यार करता है और दिन में 10 बार जाता है। अब वे पहली बार एक ही डेटाबेस सर्वर पर एक और साइट हिट करने के लिए होता है। उपर्युक्त क्वेरी में इस यूआईडी के लिए संभावित रूप से हजारों पंक्तियों के माध्यम से खोजने के लिए काफी समय लग सकता है, जो पूरे डिस्क पर बिखरे हुए हैं, क्योंकि यह इस साइट आईडी के लिए कोई नहीं ढूंढ पाएगा।

इस के रूप में संभव के रूप में कुशल बनाने पर कोई अंतर्दृष्टि की सराहना की जाएगी :)

अपडेट - इस MySQL 5.0 के साथ एक MyISAM तालिका है। मेरी चिंताओं प्रदर्शन के साथ ही भंडारण स्थान दोनों के साथ हैं। यह तालिका दोनों पढ़ी और भारी लिख रही है। अगर मुझे प्रदर्शन और भंडारण के बीच चयन करना पड़ा, तो मेरी सबसे बड़ी चिंता प्रदर्शन है - लेकिन दोनों महत्वपूर्ण हैं।

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

+0

स्टोरेज इंजन? mysql संस्करण? और आप इसे और अधिक कुशल बनाना चाहते हैं - डिस्क-उपयोग-वार या प्रदर्शन के अनुसार? और क्या आपके पास हल करने के लिए वास्तविक समस्याएं हैं या क्या यह सिर्फ एक उदार सवाल है? – ggiroux

+0

mysql 5.0, myisam इंजन। मैं स्टोरेज स्पेस के साथ-साथ प्रदर्शन दोनों के बारे में चिंतित हूं, क्योंकि यह दोनों पढ़ना और भारी तालिका लिखना है। हाँ, वास्तविक समस्या। :) – Sean

+0

क्या आपने उच्च प्रदर्शन MySQL पढ़ा है? –

उत्तर

0

सबसे पहले, यदि आप इसे आईएनटी संयुक्त हस्ताक्षर कॉलम में बदलने की तुलना में एक स्ट्रिंग के रूप में आईपी का उपयोग कर रहे हैं और इस से निपटने के लिए INET_ATON (expr) और INET_NTOA (expr) फ़ंक्शन का उपयोग करते हैं। पूर्णांक मान पर इंडेक्सिंग चर की लंबाई के तारों पर अनुक्रमण से अधिक कुशल है।

+0

सभी फ़ील्ड निश्चित रूप से पहले से ही पूर्णांक हैं ... – Sean

+0

आईपीवी 6-असंगत होना सुनिश्चित करें। वर्ष 2000, हम यहाँ आते हैं! – derobert

0

प्रदर्शन के लिए अच्छी तरह से इंडेक्स व्यापार भंडारण। यदि आप दोनों चाहते हैं तो यह मुश्किल है। आपके द्वारा चलाए जाने वाले सभी प्रश्नों और प्रति अंतराल की मात्रा के बिना इसे और अनुकूलित करने में कठिनाई होती है।

आपके पास क्या काम करेगा। यदि आप एक बाधा में भाग रहे हैं, तो आपको यह पता लगाना होगा कि उसके सीपीयू, रैम, डिस्क और/या नेटवर्क और तदनुसार समायोजित करें। समय से पहले अनुकूलित करने के लिए यह कठिन और गलत है।

यदि आपके पास कोई अपडेट है तो शायद आप innodb पर स्विच करना चाहते हैं, अन्य बुद्धिमान myisam डालने/चयन के लिए अच्छा है। चूंकि आपकी पंक्ति का आकार छोटा है, इसलिए आप mysql क्लस्टर (nbd) में देख सकते हैं। एक संग्रह इंजन भी है जो स्टोरेज आवश्यकताओं के साथ मदद कर सकता है लेकिन 5.1 में विभाजन करना संभवतः एक बेहतर चीज़ है।

आपकी अनुक्रमणिका के ऑर्डर को फ़्लिप करने से कोई अर्थ नहीं होता है, अगर ये इंडेक्स पहले से ही आपके सभी प्रश्नों में उपयोग किए जाते हैं।

लेकिन यह अधिक कुशल है कि सूचकांक का बायां सबसे अधिक स्तंभ कम से कम भिन्नता वाला है - सही?

यकीन नहीं है लेकिन मैंने पहले यह नहीं सुना है। इस एप्लिकेशन के लिए मेरे लिए सच नहीं लगता है। इंडेक्स ऑर्डर सॉर्टिंग के लिए मायने रखता है और कई अनूठे 1 सबसे अधिक इंडेक्स फ़ील्ड होने के कारण, इंडेक्स का उपयोग करने के लिए अधिक संभावित प्रश्नों की अनुमति देता है।

4
मुझे कुछ बहुत ही बुनियादी चीजों के अलावा बी-पेड़ वास्तव में समझ में नहीं आता है, लेकिन यह अधिक कुशल है कि सूचकांक का बायां सबसे अधिक स्तंभ कम से कम भिन्नता वाला है - सही?

बी पेड़ सूचकांक आप के बारे में पता करने की आवश्यकता है में से एक महत्वपूर्ण संपत्ति है: यह पूर्ण कुंजी की एक मनमाना उपसर्ग को खोजना संभव (कुशल) है, लेकिन नहीं एक प्रत्यय। यदि आपके पास इंडेक्स site_ip(site_id, ip) है, और आप where ip = 1.2.3.4 के लिए पूछते हैं, तो MySQL साइट_आईपी इंडेक्स का उपयोग नहीं करेगा। यदि आपके पास ip_site(ip, site_id) था, तो MySQL ip_site अनुक्रमणिका का उपयोग करने में सक्षम होगा।

बी-पेड़ इंडेक्स की दूसरी संपत्ति है, आपको भी इसके बारे में पता होना चाहिए: वे क्रमबद्ध हैं। where site_id < 40 जैसे प्रश्नों के लिए बी-पेड़ इंडेक्स का उपयोग किया जा सकता है।

ध्यान में रखने के लिए डिस्क ड्राइव की एक महत्वपूर्ण संपत्ति भी है: क्रमिक पढ़ने सस्ते हैं, नहीं हैं। यदि कोई कॉलम उपयोग किया गया है जो इंडेक्स में नहीं है, तो MySQL को तालिका डेटा से पंक्ति को पढ़ना होगा। यह आमतौर पर एक खोज, और धीमी है। तो अगर MySQL का मानना ​​है कि यह इस तरह की तालिका के एक छोटे प्रतिशत को भी पढ़ना बंद कर देगा, तो यह सूचकांक को अनदेखा कर देगा। एक बड़ा टेबल स्कैन (अनुक्रमिक पढ़ा जाता है) आमतौर पर तालिका में पंक्तियों के कुछ प्रतिशत के यादृच्छिक पढ़ने से तेज़ होता है।

वैसे, वैसे, एक सूचकांक के माध्यम से तलाशने पर लागू होता है। बी-पेड़ में एक कुंजी ढूंढने के लिए वास्तव में कुछ मांगों की आवश्यकता होती है, इसलिए आप पाएंगे कि WHERE site_id > 800 AND ip = '1.2.3.4'site_ip अनुक्रमणिका का उपयोग नहीं कर सकता है, क्योंकि प्रत्येक साइट_आईडी के लिए कई इंडेक्स उस साइट के 1.2.3.4 रिकॉर्ड की शुरुआत को ढूंढने की आवश्यकता है। ip_site सूचकांक, हालांकि, का उपयोग किया जाएगा।

आखिरकार, आपको अपने डेटाबेस के लिए सर्वोत्तम सूचकांक जानने के लिए बेंचमार्किंग और EXPLAIN का उदार उपयोग करना होगा। याद रखें, आप आवश्यकतानुसार इंडेक्स को स्वतंत्र रूप से जोड़ और छोड़ सकते हैं। गैर-अद्वितीय सूचकांक आपके डेटा मॉडल का हिस्सा नहीं हैं; वे केवल एक अनुकूलन हैं।

पीएस: बेंचमार्क इनो डीबी भी, यह अक्सर बेहतर समवर्ती प्रदर्शन होता है। PostgreSQL के साथ ही।

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