SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...
किसी एक्सप्रेशन या इस तरह के फ़ंक्शन के अंदर एक कॉलम का उपयोग करने से क्वेरी को अनुकूलित करने में मदद करने के लिए किसी इंडेक्स का उपयोग करके क्वेरी का कोई भी मौका खराब हो जाता है। ऊपर दिखाई गई क्वेरी को टेबल-स्कैन करने के लिए मजबूर किया जाता है।
"कुशल पहुंच" के बारे में दावा भ्रामक है। इसका मतलब है कि जब क्वेरी JSON दस्तावेज़ के साथ एक पंक्ति की जांच करती है, तो वह JSON सिंटैक्स के टेक्स्ट को पार्स किए बिना एक फ़ील्ड निकाल सकती है। लेकिन यह अभी भी पंक्तियों की खोज के लिए एक टेबल-स्कैन लेता है। दूसरे शब्दों में, क्वेरी को प्रत्येक पंक्ति की जांच करनी चाहिए।
सादृश्य से, अगर मैं "बिल" नाम वाले लोगों के लिए एक टेलीफोन बुक खोज रहा हूं, तो मुझे अभी भी फोन बुक के हर पेज को पढ़ना होगा, भले ही पहले नामों को हाइलाइट किया गया हो, ताकि उन्हें पहचानने में थोड़ी जल्दी हो।पी>
MySQL 5.7 आपको टेबल में वर्चुअल कॉलम को परिभाषित करने और फिर वर्चुअल कॉलम पर एक इंडेक्स बनाने की अनुमति देता है।
ALTER TABLE t1
ADD COLUMN series AS (JSON_EXTRACT(data, '$.series')),
ADD INDEX (series);
फिर यदि आप वर्चुअल कॉलम को क्वेरी करते हैं, तो यह इंडेक्स का उपयोग कर सकता है और टेबल-स्कैन से बच सकता है।
SELECT * FROM t1
WHERE series IN ...
यह अच्छा है, लेकिन यह JSON का उपयोग करने की बात को याद करता है। JSON का उपयोग करने का आकर्षक हिस्सा यह है कि यह आपको ALTER TABLE किए बिना नई विशेषताएँ जोड़ने की अनुमति देता है। लेकिन यह पता चला है कि यदि आप किसी इंडेक्स की मदद से JSON फ़ील्ड खोजना चाहते हैं, तो आपको एक अतिरिक्त (वर्चुअल) कॉलम को परिभाषित करना होगा।
लेकिन आपको हर . के लिए वर्चुअल कॉलम और इंडेक्स को परिभाषित करने की आवश्यकता नहीं है JSON दस्तावेज़ में फ़ील्ड—केवल वे जिन्हें आप खोजना या क्रमित करना चाहते हैं। JSON में अन्य विशेषताएँ हो सकती हैं जिन्हें आपको केवल निम्नलिखित की तरह चयन-सूची में निकालने की आवश्यकता है:
SELECT JSON_EXTRACT(data, '$.series') AS series FROM t1
WHERE <other conditions>
मैं आमतौर पर कहूंगा कि MySQL में JSON का उपयोग करने का यह सबसे अच्छा तरीका है। केवल चयन सूची में।
जब आप अन्य क्लॉज़ (जॉइन, व्हेयर, ग्रुप बाय, हैविंग, ऑर्डर बाय) में कॉलम का संदर्भ देते हैं, तो यह पारंपरिक कॉलम का उपयोग करने के लिए अधिक कुशल है, न कि JSON दस्तावेज़ों के भीतर फ़ील्ड।
मैंने MySQL में JSON का उपयोग कैसे करें नामक एक वार्ता प्रस्तुत की गलत अप्रैल 2018 में पेरकोना लाइव सम्मेलन में। मैं गिरावट में Oracle कोड वन पर बात को अपडेट और दोहराऊंगा।
JSON के साथ अन्य समस्याएं हैं। उदाहरण के लिए, मेरे परीक्षणों में इसे समान डेटा संग्रहीत करने वाले पारंपरिक स्तंभों की तुलना में JSON दस्तावेज़ों के लिए 2-3 गुना अधिक संग्रहण स्थान की आवश्यकता होती है।
MySQL अपनी नई JSON क्षमताओं को आक्रामक रूप से बढ़ावा दे रहा है, मोटे तौर पर लोगों को MongoDB में माइग्रेट करने से रोकने के लिए। लेकिन दस्तावेज़-उन्मुख डेटा संग्रहण जैसे MongoDB मूल रूप से डेटा को व्यवस्थित करने का एक गैर-संबंधपरक तरीका है। यह संबंधपरक से अलग है। मैं यह नहीं कह रहा हूं कि एक दूसरे से बेहतर है, यह सिर्फ एक अलग तकनीक है, जो विभिन्न प्रकार के प्रश्नों के अनुकूल है।
जब JSON आपके प्रश्नों को अधिक कुशल बनाता है, तो आपको JSON का उपयोग करना चुनना चाहिए।
किसी तकनीक को केवल इसलिए न चुनें क्योंकि वह नई है, या फ़ैशन के लिए।
संपादित करें:MySQL में वर्चुअल कॉलम कार्यान्वयन को इंडेक्स का उपयोग करना चाहिए यदि आपका WHERE क्लॉज वर्चुअल कॉलम की परिभाषा के समान ही अभिव्यक्ति का उपयोग करता है। अर्थात्, निम्नलिखित चाहिए वर्चुअल कॉलम पर इंडेक्स का उपयोग करें, क्योंकि वर्चुअल कॉलम AS (JSON_EXTRACT(data,"$.series"))
परिभाषित है।
SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...
सिवाय मैंने इस सुविधा का परीक्षण करके पाया है कि यह किसी कारण से काम नहीं करता है यदि अभिव्यक्ति JSON-निष्कर्षण फ़ंक्शन है। यह अन्य प्रकार के भावों के लिए काम करता है, सिर्फ JSON फ़ंक्शन के लिए नहीं। अद्यतन:यह कथित तौर पर, अंत में, MySQL 5.7.33 में काम करता है।