व्यू क्वेरी के लिए इंडेक्स का उपयोग करने के लिए आप MySQL कैसे प्राप्त करते हैं? संक्षिप्त उत्तर, एक अनुक्रमणिका प्रदान करें जिसका उपयोग MySQL कर सकता है।
इस मामले में, इष्टतम सूचकांक एक "कवरिंग" सूचकांक होने की संभावना है:
... ON highscores (player, happened_in, score)
यह संभावना है कि MySQL उस अनुक्रमणिका का उपयोग करेगा, और EXPLAIN दिखाएगा:"Using index"
WHERE player = 24
. के कारण (सूचकांक में अग्रणी कॉलम पर एक समानता विधेय। GROUP BY happened_id
(इंडेक्स में दूसरा कॉलम), MySQL को सॉर्ट ऑपरेशन से बचने के लिए इंडेक्स का उपयोग करके ऑप्टिमाइज़ करने की अनुमति दे सकता है। score
. सहित इंडेक्स में कॉलम इंडेक्स द्वारा संदर्भित डेटा पेजों पर जाने (लुकअप) किए बिना क्वेरी को पूरी तरह से इंडेक्स से संतुष्ट करने की अनुमति देगा।
वह त्वरित उत्तर है। लंबा जवाब यह है कि MySQL के happened_id
के प्रमुख कॉलम वाले इंडेक्स का उपयोग करने की बहुत संभावना नहीं है क्वेरी देखने के लिए।
दृश्य प्रदर्शन समस्या का कारण क्यों बनता है
MySQL दृश्य के साथ आपके पास एक समस्या यह है कि MySQL बाहरी क्वेरी से विधेय को दृश्य क्वेरी में "धक्का" नहीं देता है।
आपकी बाहरी क्वेरी WHERE happened_in = 2006
निर्दिष्ट करती है . MySQL ऑप्टिमाइज़र विधेय पर विचार नहीं करता है जब वह आंतरिक "व्यू क्वेरी" चलाता है। दृश्य के लिए वह क्वेरी बाहरी क्वेरी से पहले अलग से निष्पादित की जाती है। उस क्वेरी के निष्पादन से परिणाम "भौतिक" हो जाता है; अर्थात्, परिणाम एक मध्यवर्ती MyISAM तालिका के रूप में संग्रहीत किए जाते हैं। (MySQL इसे "व्युत्पन्न तालिका" कहता है, और वे जिस नाम का उपयोग करते हैं वह समझ में आता है, जब आप MysQL द्वारा किए जाने वाले संचालन को समझते हैं।)
लब्बोलुआब यह है कि जिस इंडेक्स को आपने happened_in
. पर परिभाषित किया है MySQL द्वारा उपयोग नहीं किया जा रहा है जब यह दृश्य परिभाषा बनाने वाली क्वेरी को चलाता है।
इंटरमीडिएट "व्युत्पन्न तालिका" बनने के बाद, बाहरी क्वेरी को एक पंक्ति स्रोत के रूप में "व्युत्पन्न तालिका" का उपयोग करके निष्पादित किया जाता है। यह तब होता है जब वह बाहरी क्वेरी चलती है कि happened_in = 2006
विधेय का मूल्यांकन किया जाता है।
ध्यान दें कि दृश्य क्वेरी से सभी पंक्तियां संग्रहीत हैं, जो (आपके मामले में) happened_in
के प्रत्येक मान के लिए एक पंक्ति है , केवल वही नहीं जिसे आप बाहरी क्वेरी में एक समानता विधेय निर्दिष्ट करते हैं।
क्वेरी देखने का तरीका कुछ लोगों द्वारा "अप्रत्याशित" हो सकता है, और यह एक कारण है कि MySQL में "views" का उपयोग करने से अन्य रिलेशनल डेटाबेस द्वारा दृश्य क्वेरी को संसाधित करने के तरीके की तुलना में प्रदर्शन समस्याएं हो सकती हैं।
उपयुक्त कवरिंग इंडेक्स के साथ दृश्य क्वेरी के प्रदर्शन में सुधार
आपकी दृश्य परिभाषा और आपकी क्वेरी को देखते हुए, आपको जो सबसे अच्छा मिलने वाला है, वह दृश्य क्वेरी के लिए "इंडेक्स का उपयोग करना" एक्सेस विधि होगी। इसे प्राप्त करने के लिए, आपको एक कवरिंग इंडेक्स की आवश्यकता होगी, उदा.
... ON highscores (player, happened_in, score).
आपकी मौजूदा दृश्य परिभाषा और आपकी मौजूदा क्वेरी के लिए यह सबसे अधिक लाभकारी अनुक्रमणिका (प्रदर्शन के अनुसार) होने की संभावना है। player
कॉलम प्रमुख कॉलम है क्योंकि आपके पास व्यू क्वेरी में उस कॉलम पर एक समानता विधेय है। happened_in
कॉलम अगला है, क्योंकि आपके पास उस कॉलम पर ग्रुप बाय ऑपरेशन है, और MySQL इस इंडेक्स का उपयोग ग्रुप बाय ऑपरेशन को अनुकूलित करने में सक्षम होने जा रहा है। हम score
. भी शामिल करते हैं कॉलम, क्योंकि यह आपकी क्वेरी में संदर्भित एकमात्र अन्य कॉलम है। यह इंडेक्स को "कवरिंग" इंडेक्स बनाता है, क्योंकि MySQL उस क्वेरी को सीधे इंडेक्स पेजों से संतुष्ट कर सकता है, बिना अंतर्निहित तालिका में किसी भी पेज पर जाने की आवश्यकता के बिना। और यह उतना ही अच्छा है जितना कि हम उस क्वेरी योजना से बाहर निकलने जा रहे हैं:"इंडेक्स का उपयोग करना" बिना "फाइलों का उपयोग करना"।
प्रदर्शन की तुलना बिना व्युत्पन्न तालिका वाली स्टैंडअलोन क्वेरी से करें
आप अपनी क्वेरी के लिए निष्पादन योजना की तुलना दृश्य बनाम एक समान स्टैंडअलोन क्वेरी से कर सकते हैं:
SELECT player
, MAX(score) AS highest_score
, happened_in
FROM highscores
WHERE player = 24
AND happened_in = 2006
GROUP
BY player
, happened_in
स्टैंडअलोन क्वेरी एक कवरिंग इंडेक्स का भी उपयोग कर सकती है उदा।
... ON highscores (player, happened_in, score)
लेकिन एक मध्यवर्ती MyISAM तालिका को अमल में लाने की आवश्यकता के बिना।
मुझे यकीन नहीं है कि पिछला कोई भी आपके द्वारा पूछे जा रहे प्रश्न का सीधा उत्तर प्रदान करता है।
प्रश्न:मैं MySQL को क्वेरी देखने के लिए INDEX का उपयोग करने के लिए कैसे प्राप्त करूं?
A:एक उपयुक्त INDEX परिभाषित करें जिसका उपयोग दृश्य क्वेरी कर सकती है।
संक्षिप्त उत्तर "कवरिंग इंडेक्स" प्रदान करता है (इंडेक्स में व्यू क्वेरी में संदर्भित सभी कॉलम शामिल हैं)। उस अनुक्रमणिका में प्रमुख स्तंभ ऐसे स्तंभ होने चाहिए जो समानता विधेय के साथ संदर्भित हों (आपके मामले में, स्तंभ player
एक प्रमुख कॉलम होगा क्योंकि आपके पास एक player = 24
. है क्वेरी में विधेय। साथ ही, GROUP BY में संदर्भित कॉलम इंडेक्स में अग्रणी कॉलम होने चाहिए, जो MySQL को GROUP BY
को ऑप्टिमाइज़ करने की अनुमति देता है। सॉर्ट ऑपरेशन का उपयोग करने के बजाय इंडेक्स का उपयोग करके ऑपरेशन।
यहां मुख्य बिंदु यह है कि दृश्य क्वेरी मूल रूप से एक स्टैंडअलोन क्वेरी है; उस क्वेरी के परिणाम एक इंटरमीडिएट "व्युत्पन्न" तालिका में संग्रहीत हो जाते हैं (एक MyISAM तालिका जो तब बनती है जब दृश्य के विरुद्ध कोई क्वेरी चलती है।
MySQL में विचारों का उपयोग करना एक "बुरा विचार" नहीं है, लेकिन मैं उन लोगों को दृढ़ता से सावधान करता हूं जो MySQL के भीतर विचारों का उपयोग करने के लिए चुनते हैं कि कैसे MySQL उन विचारों का संदर्भ देने वाले प्रश्नों को संसाधित करता है। और जिस तरह से MySQL प्रोसेस क्वेश्चन को देखता है वह अन्य डेटाबेस (जैसे Oracle, SQL सर्वर) द्वारा व्यू क्वेश्चन को हैंडल करने के तरीके से अलग (महत्वपूर्ण) है।