- क्योंकि
avg_row_length
data_length / rows
है ।
data_length
मूल रूप से डिस्क पर तालिका का कुल आकार है . एक InnoDB तालिका केवल पंक्तियों की सूची से अधिक है। तो वह अतिरिक्त ओवरहेड है।
- चूंकि एक InnoDB पंक्ति डेटा से अधिक है।
ऊपर के समान, प्रत्येक पंक्ति कुछ ओवरहेड के साथ आती है। तो यह एक पंक्ति के आकार में जोड़ने वाला है। एक InnoDB तालिका भी केवल एक साथ भरे हुए डेटा की एक सूची नहीं है। इसे कुशलता से काम करने के लिए थोड़ी अतिरिक्त खाली जगह चाहिए।
- चूंकि सामग्री डिस्क पर ब्लॉक में संग्रहीत होती है और वे ब्लॉक हमेशा भरे नहीं होते हैं।
डिस्क सामान को आमतौर पर 4K, 8K या 16K ब्लॉक में स्टोर करती है . कभी-कभी चीजें उन ब्लॉक में पूरी तरह फिट नहीं होती हैं, इसलिए आप कुछ खाली पा सकते हैं अंतरिक्ष ।
जैसा कि हम नीचे देखेंगे, MySQL तालिका को ब्लॉक में आवंटित करने जा रहा है। और यह तालिका को बढ़ने से बचने के लिए आवश्यकता से अधिक आवंटित करने जा रहा है (जो धीमा हो सकता है और डिस्क विखंडन जो चीजों को और भी धीमा कर देता है)।
इसे स्पष्ट करने के लिए, आइए एक खाली टेबल से शुरुआत करें।
mysql> create table foo ( id smallint(5) unsigned NOT NULL );
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
| 16384 | 0 | 0 |
+-------------+------------+----------------+
यह कुछ भी स्टोर करने के लिए 16K, या चार 4K ब्लॉक का उपयोग नहीं करता है। खाली तालिका को इस स्थान की आवश्यकता नहीं है, लेकिन MySQL ने इसे इस धारणा पर आवंटित किया है कि आप इसमें डेटा का एक गुच्छा डालने जा रहे हैं। यह प्रत्येक इंसर्ट पर एक महँगा पुनः आबंटन करने से बचा जाता है।
अब एक पंक्ति जोड़ते हैं।
mysql> insert into foo (id) VALUES (1);
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
| 16384 | 1 | 16384 |
+-------------+------------+----------------+
तालिका कोई बड़ी नहीं हुई, उन 4 ब्लॉकों के भीतर वह सब अप्रयुक्त स्थान है जो उसके पास है। एक पंक्ति है जिसका अर्थ है 16K की avg_row_length। स्पष्ट रूप से बेतुका। आइए एक और पंक्ति जोड़ें।
mysql> insert into foo (id) VALUES (1);
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
| 16384 | 2 | 8192 |
+-------------+------------+----------------+
एक ही बात। तालिका के लिए 16K आवंटित किया गया है, उस स्थान का उपयोग करके 2 पंक्तियां। प्रति पंक्ति 8K का एक बेतुका परिणाम।
जैसे-जैसे मैं अधिक से अधिक पंक्तियाँ सम्मिलित करता हूँ, तालिका का आकार समान रहता है, यह अपने आवंटित स्थान का अधिक से अधिक उपयोग कर रहा है, और avg_row_length
वास्तविकता के करीब आता है।
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
| 16384 | 2047 | 8 |
+-------------+------------+----------------+
यहाँ भी हम table_rows
see देखना शुरू करते हैं गलत हो जाना। मैंने निश्चित रूप से 2048 पंक्तियाँ डाली हैं।
अब जब मैं कुछ और सम्मिलित करता हूँ...
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
| 98304 | 2560 | 38 |
+-------------+------------+----------------+
(मैंने 512 पंक्तियाँ डालीं, और table_rows
किसी कारण से वास्तविकता में वापस आ गया है)
MySQL ने तय किया कि तालिका को अधिक स्थान की आवश्यकता है, इसलिए इसका आकार बदल गया और एक गुच्छा अधिक डिस्क स्थान पकड़ लिया। avg_row_length
बस फिर से कूद गया।
इसने उन 512 पंक्तियों के लिए आवश्यकता से बहुत अधिक स्थान हथिया लिया, अब यह 96K या 24 4K ब्लॉक है, इस धारणा पर कि इसे बाद में इसकी आवश्यकता होगी। यह कम से कम संभावित रूप से धीमी गति से वास्तविक स्थानों को करने की आवश्यकता है और डिस्क विखंडन को कम करता है।
इसका मतलब यह नहीं है कि वह सारा स्थान भर गया था . इसका सीधा सा मतलब है कि MySQL ने सोचा था कि कुशलतापूर्वक चलाने के लिए और अधिक जगह की आवश्यकता के लिए पर्याप्त था। यदि आप एक विचार चाहते हैं कि ऐसा क्यों है, तो देखें कि कैसे एक हैश तालिका कार्य करता है। मुझे नहीं पता कि InnoDB एक हैश तालिका का उपयोग करता है या नहीं, लेकिन सिद्धांत लागू होता है:कुछ डेटा संरचनाएं कुछ खाली जगह होने पर सबसे अच्छा काम करती हैं।
तालिका द्वारा उपयोग की जाने वाली डिस्क तालिका में पंक्तियों की संख्या और स्तंभों के प्रकार से सीधे संबंधित होती है, लेकिन सटीक सूत्र का पता लगाना मुश्किल होता है और यह संस्करण से MySQL के संस्करण में बदल जाएगा। आपका सबसे अच्छा दांव कुछ अनुभवजन्य परीक्षण करना और खुद को इस्तीफा देना है कि आपको कभी भी सटीक संख्या नहीं मिलेगी।