5 मिनट
सबग्राफ सर्वश्रेष्ठ प्रथा 3 - अपरिवर्तनीय संस्थाओं और बाइट्स को आईडी के रूप में उपयोग करके अनुक्रमण और क्वेरी प्रदर्शन में सुधार करें।
TLDR
हमारे schema.graphql फ़ाइल में अमूर्त एंटिटीज और आईडी के लिए बाइट्स का उपयोग सूचक गति और क्वेरी प्रदर्शन में महत्वपूर्ण सुधार करता है।
अमूर्त एंटिटीज
एक एंटिटी को अमूर्त बनाने के लिए, हम बस एंटिटी में (immutable: true) जोड़ते हैं।
1type Transfer @entity(immutable: true) {2 id: Bytes!3 from: Bytes!4 to: Bytes!5 value: BigInt!6}
Transfer एंटिटी को अमूर्त बनाने से, graph-node एंटिटी को अधिक कुशलता से संसाधित कर सकता है, जिससे indexing गति और क्वेरी की प्रतिक्रिया में सुधार होता है।
Immutable Entities structures will not change in the future. An ideal entity to become an Immutable Entity would be an entity that is directly logging onchain event data, such as a Transfer
event being logged as a Transfer
entity.
हुड के नीचे
परिवर्तनीय एंटिटियों में एक ‘ब्लॉक रेंज’ होती है जो उनकी वैधता को इंगित करती है। इन एंटिटियों को अपडेट करने के लिए ग्राफ नोड को पिछले संस्करणों की ब्लॉक रेंज को समायोजित करना पड़ता है, जिससे डेटाबेस का कार्यभार बढ़ जाता है। क्वेरियों को भी केवल जीवित एंटिटियों को खोजने के लिए फ़िल्टर करने की आवश्यकता होती है। अमूर्त एंटिटियाँ तेज होती हैं क्योंकि ये सभी जीवित होती हैं और चूंकि ये नहीं बदलेंगी, लिखते समय किसी भी चेक या अपडेट की आवश्यकता नहीं होती, और क्वेरियों के दौरान कोई फ़िल्टरिंग की आवश्यकता नहीं होती।
अमूर्त एंटिटीज का उपयोग कब न करें
अगर आपके पास एक ऐसा फ़ील्ड है जैसे status जिसे समय के साथ संशोधित करने की आवश्यकता है, तो आपको एंटिटी को अमूर्त नहीं बनाना चाहिए। अन्यथा, आपको जब भी संभव हो, अमूर्त एंटिटीज का उपयोग करना चाहिए।
Bytes को IDs के रूप में
हर एंटिटी के लिए एक ID की आवश्यकता होती है। पिछले उदाहरण में, हम देख सकते हैं कि ID पहले से ही Bytes प्रकार की है।
1type Transfer @entity(immutable: true) {2 id: Bytes!3 from: Bytes!4 to: Bytes!5 value: BigInt!6}
हालांकि IDs के लिए अन्य प्रकार संभव हैं, जैसे String और Int8, लेकिन सभी IDs के लिए Bytes प्रकार का उपयोग करने की सिफारिश की जाती है क्योंकि चरित्र स्ट्रिंग्स को बाइनरी डेटा संग्रहीत करने के लिए बाइट स्ट्रिंग्स की तुलना में दोगुना स्थान चाहिए, और UTF-8 चरित्र स्ट्रिंग्स की तुलना करते समय स्थानीय भाषा का ध्यान रखना आवश्यक है, जो बाइट स्ट्रिंग्स की तुलना के लिए उपयोग की जाने वाली बाइटवाइज तुलना की तुलना में बहुत अधिक महंगा है।
IDs के रूप में Bytes का उपयोग न करने के कारण
- यदि एंटिटी IDs मानव-पठनीय होने चाहिए, जैसे कि ऑटो-इंक्रीमेंटेड न्यूमेरिकल IDs या पठनीय स्ट्रिंग्स, तो IDs के लिए Bytes का उपयोग नहीं किया जाना चाहिए।
- If integrating a Subgraph’s data with another data model that does not use Bytes as IDs, Bytes as IDs should not be used.
- Indexing और क्वेरीिंग प्रदर्शन में सुधार की आवश्यकता नहीं है।
Bytes के रूप में IDs के साथ जोड़ना
It is a common practice in many Subgraphs to use string concatenation to combine two properties of an event into a single ID, such as using event.transaction.hash.toHex() + "-" + event.logIndex.toString()
. However, as this returns a string, this significantly impedes Subgraph indexing and querying performance.
इसके बजाय, हमें event properties को जोड़ने के लिए concatI32() method का उपयोग करना चाहिए। यह रणनीति एक Bytes ID उत्पन्न करती है जो बहुत अधिक performant होती है।
1export function handleTransfer(event: TransferEvent): void {2 let entity = new Transfer(event.transaction.hash.concatI32(event.logIndex.toI32()))3 entity.from = event.params.from4 entity.to = event.params.to5 entity.value = event.params.value67 entity.blockNumber = event.block.number8 entity.blockTimestamp = event.block.timestamp9 entity.transactionHash = event.transaction.hash1011 entity.save()12}
Bytes के रूप में IDs के साथ क्रमबद्ध करना
Bytes को IDs के रूप में उपयोग करके क्रमबद्ध करना इस उदाहरण क्वेरी और प्रतिक्रिया में देखे गए अनुसार उपयुक्त नहीं है।
Query:
1{2 transfers(first: 3, orderBy: id) {3 id4 from5 to6 value7 }8}
प्रश्न प्रतिक्रिया:
1{2 "data": {3 "transfers": [4 {5 "id": "0x00010000",6 "from": "0xabcd...",7 "to": "0x1234...",8 "value": "256"9 },10 {11 "id": "0x00020000",12 "from": "0xefgh...",13 "to": "0x5678...",14 "value": "512"15 },16 {17 "id": "0x01000000",18 "from": "0xijkl...",19 "to": "0x9abc...",20 "value": "1"21 }22 ]23 }24}
IDs,hex के रूप में वापस किए जाते हैं।
क्रमबद्धता में सुधार करने के लिए, हमें इकाई पर एक और फ़ील्ड बनानी चाहिए जो एक BigInt हो।
1type Transfer @entity {2 id: Bytes!3 from: Bytes! # address4 to: Bytes! # address5 value: BigInt! # unit2566 tokenId: BigInt! # uint2567}
इससे क्रमबद्धता को क्रमिक रूप से अनुकूलित करने की अनुमति मिलेगी।
Query:
1{2 transfers(first: 3, orderBy: tokenId) {3 id4 tokenId5 }6}
प्रश्न प्रतिक्रिया:
1{2 "data": {3 "transfers": [4 {5 "id": "0x…",6 "tokenId": "1"7 },8 {9 "id": "0x…",10 "tokenId": "2"11 },12 {13 "id": "0x…",14 "tokenId": "3"15 }16 ]17 }18}
निष्कर्ष
Using both Immutable Entities and Bytes as IDs has been shown to markedly improve Subgraph efficiency. Specifically, tests have highlighted up to a 28% increase in query performance and up to a 48% acceleration in indexing speeds.
इस ब्लॉग पोस्ट में, Edge & Node के सॉफ़्टवेयर इंजीनियर डेविड लुटरकोर्ट द्वारा Immutable Entities और Bytes को IDs के रूप में उपयोग करने के बारे में और अधिक पढ़ें: दो सरल Subgraph प्रदर्शन सुधार।.