मेरे पास एक सारणी है जो तृतीय पक्ष वेबसाइटों पर विज़िटर सत्रों के बारे में कुछ बुनियादी डेटा संग्रहीत करती है। यह इसकी संरचना है:एकाधिक इंडेक्स वाले तालिका के लिए 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 का उपयोग करते हैं, लेकिन डेटाबेस डिजाइन के बारे में परवाह नहीं करने का बहाना नहीं है। मैं डेटाबेस को जितना संभव हो उतना कुशल होना चाहता हूं।
स्टोरेज इंजन? mysql संस्करण? और आप इसे और अधिक कुशल बनाना चाहते हैं - डिस्क-उपयोग-वार या प्रदर्शन के अनुसार? और क्या आपके पास हल करने के लिए वास्तविक समस्याएं हैं या क्या यह सिर्फ एक उदार सवाल है? – ggiroux
mysql 5.0, myisam इंजन। मैं स्टोरेज स्पेस के साथ-साथ प्रदर्शन दोनों के बारे में चिंतित हूं, क्योंकि यह दोनों पढ़ना और भारी तालिका लिखना है। हाँ, वास्तविक समस्या। :) – Sean
क्या आपने उच्च प्रदर्शन MySQL पढ़ा है? –