2015-04-17 7 views
24

मान लीजिए मैं एक स्तंभ परिवार है:माध्यमिक अनुक्रमणिका कैसंद्रा में कैसे काम करते हैं?

CREATE TABLE update_audit (
    scopeid bigint, 
    formid bigint, 
    time timestamp, 
    record_link_id bigint, 
    ipaddress text, 
    user_zuid bigint, 
    value text, 
    PRIMARY KEY ((scopeid, formid), time) 
) WITH CLUSTERING ORDER BY (time DESC) 
दो माध्यमिक अनुक्रमित के साथ

, जहां record_link_id में एक अत्यधिक-स्तंभ है:

CREATE INDEX update_audit_id_idx ON update_audit (record_link_id); 

CREATE INDEX update_audit_user_zuid_idx ON update_audit (user_zuid); 

मेरी जानकारी कैसेंड्रा तो जैसे दो छिपा स्तंभ परिवारों पैदा करेगा के अनुसार :

CREATE TABLE update_audit_id_idx(
    record_link_id bigint, 
    scopeid bigint, 
    formid bigint, 
    time timestamp 
    PRIMARY KEY ((record_link_id), scopeid, formid, time) 
); 

CREATE TABLE update_audit_user_zuid_idx(
    user_zuid bigint, 
    scopeid bigint, 
    formid bigint, 
    time timestamp 
    PRIMARY KEY ((user_zuid), scopeid, formid, time) 
); 

कैसंड्रा माध्यमिक इंडेक्स को मानक इंडेक्स के रूप में वितरित किए जाने के बजाय स्थानीय इंडेक्स के रूप में लागू किया जाता है एल टेबल प्रत्येक नोड केवल उस डेटा के लिए एक इंडेक्स स्टोर करता है जो इसे स्टोर करता है।

select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897; 
  1. कैसे इस क्वेरी कैसेंड्रा में 'हुड के नीचे' पर अमल होगा:

    निम्न क्वेरी पर विचार करें?

  2. उच्च-कार्डिनिटी कॉलम इंडेक्स (record_link_id) इसके प्रदर्शन को कैसे प्रभावित करेगा?
  3. क्या कैसंद्रा उपरोक्त क्वेरी के लिए सभी नोड्स को छूएगा? क्यों?
  4. कौन सा मानदंड पहले निष्पादित किया जाएगा, बेस टेबल partition_key या द्वितीयक अनुक्रमणिका partition_key? कैसंद्रा इन दो परिणामों को कैसे छेड़छाड़ करेगा?
+0

मेरा 2 सेंट: चूंकि आपने एक पूर्ण विभाजन कुंजी निर्दिष्ट की है, इसलिए सभी नोड्स से पूछताछ करने का कोई मतलब नहीं है। यह स्पष्ट रूप से केवल एक नोड से पूछताछ (35, 78005) के लिए जिम्मेदार होना चाहिए। जिस तरह से कैसंद्रा डिज़ाइन किया गया है, मैं उम्मीद करता हूं कि इसमें प्राथमिकता के रूप में शामिल नोड्स की संख्या को कम करने पर विचार करें। यह देखते हुए कि, केवल शामिल नोड को शायद यह देखना चाहिए कि इसके लिए कितने रिकॉर्ड हैं (35, 78005) और 'record_link_id = 9897' के लिए इंडेक्स में कितने हैं, और क्वेरी (जो' सूचकांक को प्राथमिक कुंजी द्वारा क्रमबद्ध किया गया है या नहीं, इस पर निर्भर करता है कि यह सबसे छोटा है)। –

+0

मेरा सिद्धांत http://docs.datastax.com/en/cql/3.0/cql/ddl/ddl_using_multiple_indexes.html –

+0

द्वारा समर्थित होने पर प्रतीत होता है यदि यह तरीका है, तो उच्च-कार्डिनिटी कॉलम पर इंडेक्स बनाना सबसे तेज़ होगा और सर्वोत्तम डेटा मॉडल (यदि आप मानदंड में विभाजन कुंजी भी शामिल हैं)। – Aftab

उत्तर

38
select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897; 

कैसे ऊपर क्वेरी कैसेंड्रा में आंतरिक रूप से काम करेंगे?

अनिवार्य रूप से, विभाजन scopeid=35 और formid=78005 के लिए सभी डेटा वापस आ जाएगा, और फिर record_link_id सूचकांक द्वारा फ़िल्टर। यह 9897 के लिए प्रविष्टि की तलाश करेगा, और scopeid=35 और formid=78005 पर लौटाई गई पंक्तियों से मेल खाने वाली प्रविष्टियों को मिलान करने का प्रयास करेगा। विभाजन कुंजी और अनुक्रमणिका कुंजी के लिए पंक्तियों का चौराहे वापस कर दिया जाएगा।

उच्च-कार्डिनालिटी कॉलम (record_link_id) अनुक्रमणिका उपर्युक्त क्वेरी के लिए क्वेरी प्रदर्शन को कैसे प्रभावित करेगा?

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

क्या कैसंड्रा उपरोक्त क्वेरी के लिए सभी नोड्स को छूएगा? क्यूं कर?

नहीं। यह केवल एक नोड कि scopeid=35 और formid=78005 विभाजन के लिए जिम्मेदार है स्पर्श करना चाहिए। इसी प्रकार इंडेक्स को स्थानीय रूप से संग्रहीत किया जाता है, केवल स्थानीय नोड के लिए मान्य प्रविष्टियां होती हैं।

अत्यधिक-स्तंभों पर बनाने सूचकांक सबसे तेज और सबसे अच्छा डाटा मॉडल

समस्या है कि यहाँ दृष्टिकोण पैमाने पर नहीं है हो जाएगा, और धीमी गति से हो सकता है अगर update_audit एक बड़ी डाटासेट है।

तो अपनी मेज स्मृति तुलना में काफी बड़ा था, एक प्रश्न बहुत भी सिर्फ कुछ हजार प्रणाली परिणामों को धीमी गति से होगा: एमवीपी रिचर्ड कम माध्यमिक अनुक्रमित पर एक बड़ा लेख (The Sweet Spot For Cassandra Secondary Indexing), और विशेष रूप से इस मुद्दे पर है। संभावित रूप से लाखों उपयोगकर्ताओं को लौटने से विनाशकारी होगा, भले ही यह एक कुशल क्वेरी प्रतीत होता है।

...

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

अब, एक विशिष्ट विभाजन द्वारा पहली बार प्रतिबंधित करने का आपका दृष्टिकोण मदद करेगा (क्योंकि आपका विभाजन निश्चित रूप से स्मृति में फिट होना चाहिए)। लेकिन मुझे लगता है कि बेहतर प्रदर्शन करने वाला विकल्प यहां एक माध्यमिक सूचकांक पर निर्भर होने के बजाय record_link_id क्लस्टरिंग कुंजी बनाना होगा।

संपादित

कैसे करता है कम प्रमुखता सूचकांक पर होने सूचकांक जब उपयोगकर्ताओं के लाखों लोगों भी पैमाने पर जब हम प्राथमिक कुंजी

प्रदान देखते हैं यह कैसे विस्तृत अपनी पंक्तियों पर निर्भर करेगा । बेहद कम कार्डिनालिटी इंडेक्स के बारे में मुश्किल बात यह है कि लौटाई गई पंक्तियों का% आमतौर पर अधिक होता है। उदाहरण के लिए, एक विस्तृत पंक्ति users तालिका पर विचार करें। आप अपनी क्वेरी में विभाजन कुंजी से प्रतिबंधित हैं, लेकिन अभी भी 10,000 पंक्तियां लौट आई हैं। यदि आपकी अनुक्रमणिका gender जैसी किसी चीज़ पर है, तो आपकी क्वेरी को उन पंक्तियों में से आधा फ़िल्टर करना होगा, जो अच्छी तरह से प्रदर्शन नहीं करेंगे।

माध्यमिक सूचकांक "बेहतर वर्णन की कमी के लिए)" सड़क के बीच "कार्डिनिटी पर सबसे अच्छा काम करते हैं। विस्तृत पंक्ति users तालिका के उपरोक्त उदाहरण का उपयोग करते हुए, country या state पर एक सूचकांक gender पर एक इंडेक्स से काफी बेहतर प्रदर्शन करना चाहिए (मानते हैं कि उनमें से अधिकतर उपयोगकर्ता एक ही देश या राज्य में नहीं रहते हैं)।

+2

सामान्य रूप से पूर्ण और अंतर्दृष्टि। – phact

+0

बढ़िया !, कुछ भी नहीं पूछने के लिए छोड़ दिया। धन्यवाद। – Aftab

+0

अंतर्दृष्टि के लिए धन्यवाद! कम कार्डिनालिटी इंडेक्स पर इंडेक्स कैसे होता है जब लाखों उपयोगकर्ता स्केल करते हैं तब भी जब हम क्वेरी में विभाजन कुंजी प्रदान करते हैं जैसे 'select * उपयोगकर्ता partkey = x और लिंग =' एम 'से। भंडारण परिप्रेक्ष्य से, लिंग पर छुपा स्तंभ परिवार, क्या यह बहती नहीं है? क्या यह समस्या का कारण बन जाएगा क्योंकि परिणाम को फ़िल्टर करने के लिए इसे छिपे हुए कॉलम परिवार के माध्यम से स्कैन करने की आवश्यकता है? http://stackoverflow.com/questions/29659564/validating-row-at-client-side-better-than-secondary-index-with-whole-primary-key – pinkpanther

2

केवल माध्यमिक सूचकांक के साथ क्वेरी कैसेंड्रा 2.x में भी संभव है

चयन * update_audit से जहां record_link_id = 9897;

लेकिन इसका डेटा लाने पर एक बड़ा प्रभाव पड़ता है, क्योंकि यह वितरित वातावरण पर सभी विभाजन पढ़ता है। इस क्वेरी द्वारा प्राप्त डेटा भी सुसंगत नहीं है और इस पर रिले नहीं कर सका।

सुझाव: माध्यमिक सूचकांक के
उपयोग NoSQL डेटा मॉडल दृश्य से धूल क्वेरी माना जाता है।

माध्यमिक अनुक्रमणिका से बचने के लिए, हम एक नई तालिका बना सकते हैं और डेटा कॉपी कर सकते हैं।चूंकि यह एप्लिकेशन की एक क्वेरी है, टेबल्स क्वेरी से व्युत्पन्न हैं।

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