MySQL क्वेरी ऑप्टिमाइज़र कहाँ से सूचकांक आँकड़े पढ़ता है?


14

मैं यह निर्धारित करने की कोशिश कर रहा हूं कि MySQL ऑप्टिमाइज़र उन सूचियों की सूची प्राप्त करता है जो तालिका के लिए उपलब्ध हैं, जब यह किसी क्वेरी की लागत (तैयारी) का अनुमान लगाता है।


+1 इस अच्छे प्रश्न के लिए क्योंकि डेवलपर्स और डीबीए को यह सोचना चाहिए कि सूचकांक के आंकड़े कैसे संकलित और संग्रहीत किए जाते हैं।
रोलैंडमाइसीडीडीबीए

संदर्भ के लिए, mysql प्रलेखन वेबसाइट से: < dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html >> ANALYZE TABLEसूचकांक कार्डिनैलिटी निर्धारित करता है (जैसा कि SHOW INDEXआउटपुट के कार्डिनैलिटी कॉलम में प्रत्येक को आठ यादृच्छिक डाइव करके दिखाया गया है ) सूचकांक पेड़ों और अद्यतन सूचकांक कार्डिनैलिटी के अनुसार अनुमान। क्योंकि ये केवल अनुमान हैं, ANALYZE TABLE के बार-बार चलने से विभिन्न संख्याएँ उत्पन्न हो सकती हैं। यह ANALYZE TABLEInnoDB तालिकाओं पर उपवास करता है लेकिन 100% सटीक नहीं है क्योंकि यह सभी पंक्तियों को ध्यान में नहीं रखता है।
चेन झी

जवाबों:


6

इसका सीधा जवाब होगा

information_schema.statistics

mysql> desc information_schema.statistics;
+---------------+---------------+------+-----+---------+-------+
| Field         | Type          | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(512)  | NO   |     |         |       |
| TABLE_SCHEMA  | varchar(64)   | NO   |     |         |       |
| TABLE_NAME    | varchar(64)   | NO   |     |         |       |
| NON_UNIQUE    | bigint(1)     | NO   |     | 0       |       |
| INDEX_SCHEMA  | varchar(64)   | NO   |     |         |       |
| INDEX_NAME    | varchar(64)   | NO   |     |         |       |
| SEQ_IN_INDEX  | bigint(2)     | NO   |     | 0       |       |
| COLUMN_NAME   | varchar(64)   | NO   |     |         |       |
| COLLATION     | varchar(1)    | YES  |     | NULL    |       |
| CARDINALITY   | bigint(21)    | YES  |     | NULL    |       |
| SUB_PART      | bigint(3)     | YES  |     | NULL    |       |
| PACKED        | varchar(10)   | YES  |     | NULL    |       |
| NULLABLE      | varchar(3)    | NO   |     |         |       |
| INDEX_TYPE    | varchar(16)   | NO   |     |         |       |
| COMMENT       | varchar(16)   | YES  |     | NULL    |       |
| INDEX_COMMENT | varchar(1024) | NO   |     |         |       |
+---------------+---------------+------+-----+---------+-------+
16 rows in set (0.01 sec)

आप उस तालिका से चयन कर सकते हैं

SELECT * FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='mytable';

या आंकड़ों को करके देखें

Mydb.mytable से शो के सूचकांक;

कृपया ध्यान रखें कि यह तालिका लेखन-भारी वातावरण में हमेशा सटीक नहीं होती है। समय-समय पर आपको उन सभी MyISAM तालिकाओं के विरुद्ध ANALYZE TABLE चलाना होगा जो अक्सर अपडेट की जाती हैं। अन्यथा, MySQL क्वेरी ऑप्टिमाइज़र, जो info_schema.statistics पर निर्भर करता है, कभी-कभी प्रश्नों के लिए EXPLAIN योजनाओं को विकसित करते समय खराब विकल्प बना सकता है। सूचकांक के आँकड़े यथासंभव अद्यतित होने चाहिए।

ANALYZE टेबल में InnoDB तालिकाओं के खिलाफ ABSOLUTELY NO EFFECT है। InnoDB के लिए सभी सूचकांक आँकड़े BTREE पृष्ठों में गोता लगाने के माध्यम से मांग पर गणना की जाती है। इसलिए, जब आप एक InnoDB तालिका के विरुद्ध SHOW INDEXES FROM चलाते हैं, तो प्रदर्शित कार्डिनैलिटी हमेशा सन्निकटन होती है।

UPDATE 2011-06-21 12:17 EDT

ANALYZE TABLE के स्पष्टीकरण के लिए, मुझे rephrase दें। InnoDB तालिकाओं पर ANALYZE टेबल चलाना पूरी तरह से बेकार है। यहां तक ​​कि अगर आप एक InnoDB टेबल पर ANALYZE टेबल को चलाते हैं, तो InnoDB भंडारण इंजन बार-बार कार्डिनैलिटी सन्निकटन के लिए इंडेक्स में डाइव करता है, इस प्रकार आपके द्वारा संकलित आँकड़ों को रौंद देता है । वास्तव में, Percona ने ANALYZE TABLE पर कुछ परीक्षण किए और उस निष्कर्ष पर भी आए।


5

पुन :: ANALYZE टेबल में InnoDB तालिकाओं के खिलाफ ABSOLUTELY NO EFFECT है।

मुझे यकीन नहीं है कि यह कथन सत्य है। हमारे पास भारी-भरकम पढ़ने और लिखने की मेज है और जब mysql ऑप्टिमाइज़र खराब विकल्प बनाता है, तो क्वेरी का व्याख्या आउटपुट खराब रणनीति दिखाता है। और इनोडब टेबल से शो इंडेक्स उनके कार्डिनैलिटी वैल्यूज में बहुत अधिक बदलाव दिखाता है। लेकिन उन निर्दोष तालिकाओं पर एक ANALYZE कमांड चलाने से स्पष्टीकरण योजना ठीक हो जाती है और कार्डिनलिटी के विचरण व्यवहार को भी दूर कर देती है। मुझे नहीं पता कि क्या इनोडब टेबलों पर ANALYZE टेबल कमांड हर समय मदद करता है या नहीं, लेकिन हमारे मामले में, इसने लगभग 99% समय की मदद की।

हमने अपने प्रश्नों में "STRAIGHT_JOIN" को शामिल करके mysql अनुकूलक के बुरे विकल्प को पूरी तरह से समाप्त कर दिया है। इसने mysql ऑप्टिमाइज़र को बुरा विकल्प या कोई भी विकल्प नहीं बनाने के लिए मजबूर किया, लेकिन जैसा कि हमने क्वेरी में परिभाषित किया है, वैसे ही JOIN शर्त का पालन करें।


मैंने InnoDB तालिकाओं पर ANALYZE टेबल की बेकारता को उजागर करने के लिए अपना जवाब अपडेट किया।
रोलैंडमाइसीडीडीबीए

जब आप कार्डिनलिटी में विचरण का उल्लेख करते हैं तो मैं आपके उत्तर से सहमत होता हूं। ठीक यही बात मैं तब कह रहा था जब मैंने कार्डिनैलिटी का अनुमान लगाया था।
RolandoMySQLDBA

मुझे यह भी उल्लेख करने की आवश्यकता है कि प्रश्नों में संकेत का उपयोग करना हमेशा सबसे अच्छी बात नहीं है जब MySQL क्वेरी ऑप्टिमाइज़र उन्हें समय पर समाप्त करने के लिए जाता है। यहां उन प्रश्नों का एक लिंक दिया गया है जो आंतरिक रूप से क्वेरी से संबंधित होते हैं जो वास्तव में डेटा को क्वेरी योजनाओं के कुछ हिस्सों में गायब कर सकते हैं: dba.stackexchange.com/questions/1371/…
RolandoMySQLDBA

2

MyISAM के लिए विश्लेषण तालिका पूरी तालिका को स्कैन करती है और आँकड़े को पुनर्निर्मित करती है, जिसे .MYI फ़ाइल में सहेजा जाता है। इसकी जरूरत शायद ही हो।

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

नए संस्करण 8 (नहीं) यादृच्छिक यादृच्छिक जांच (1) को और अधिक यादृच्छिक (2) में बदलने की अनुमति देते हैं, जिससे आप "8" को बदल सकते हैं (इस के पेशेवरों और विपक्ष हैं!), और (3) पुनरारंभ के दौरान बचत करते हैं।

नीचे पंक्ति: InnoDB अभी भी इसे 'सही' नहीं मिला है। जब आप ऐसा महसूस करते हैं तो एनालाइज करें, लेकिन अपनी सांस को रोककर न रखें।

अपडेट करें

फिर से वाक्यांश ... करने ANALYZE TABLEके लिए एक अस्थायी प्रभाव है (संभवतः लाभप्रद, संभवतः नहीं) InnoDB तालिकाओं के अनुकूलन पर।

"नया संस्करण": 5.6.6 (2012) और मारियाडीबी 10.1 (2014) के साथ शुरुआत करते हुए, आंकड़े बहुत बेहतर तरीके से संभाले जाते हैं, और ANALYZEअब (1) कम अक्सर आवश्यक होते हैं, और (2) अधिक स्थायी होते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.