MySQL
प्रदर्शन सुधारना
खोज…
वाक्य - विन्यास
उसी चयन में DISTINCT और GROUP BY का उपयोग न करें।
OFFSET के माध्यम से मत सोचो, "याद रखें कि आपने कहाँ छोड़ा था"।
जहां (ए, बी) = (22,33) बिल्कुल भी अनुकूलन नहीं करता है।
स्पष्ट रूप से कहें कि UN के बाद ALL या DISTINCT - यह याद दिलाता है कि आप तेज ALL या धीमे DISTINCT के बीच चुनें।
चयन करें * का उपयोग न करें, खासकर यदि आपके पास टीबीटी या बीएलओबी कॉलम हैं जिनकी आपको आवश्यकता नहीं है। टीएमपी टेबल और ट्रांसमिशन में ओवरहेड है।
जब समूह BY और ORDER BY एक ही सूची में हो सकते हैं तो यह तेजी से होता है।
FORCE INDEX का उपयोग न करें; यह आज मदद कर सकता है, लेकिन शायद कल चोट लगी होगी।
टिप्पणियों
ORDER BY, LIKE, REGEXP, आदि के बारे में भी चर्चा देखें। नोट: लिंक और अधिक विषयों के साथ संपादन की आवश्यकता है।
सही इंडेक्स जोड़ें
यह एक बहुत बड़ा विषय है, लेकिन यह सबसे महत्वपूर्ण "प्रदर्शन" मुद्दा भी है।
नौसिखिए के लिए मुख्य सबक "समग्र" अनुक्रमित सीखना है। यहाँ एक त्वरित उदाहरण है:
INDEX(last_name, first_name)
इन के लिए उत्कृष्ट है:
WHERE last_name = '...'
WHERE first_name = '...' AND last_name = '...' -- (order in WHERE does not matter)
लेकिन इसके लिए नहीं
WHERE first_name = '...' -- order in INDEX _does_ matter
WHERE last_name = '...' OR first_name = '...' -- "OR" is a killer
कैश को सही तरीके से सेट करें
innodb_buffer_pool_size
उपलब्ध रैम का लगभग 70% होना चाहिए।
अकुशल निर्माण से बचें
x IN ( SELECT ... )
एक JOIN
में JOIN
जब संभव हो, से बचने OR
।
किसी फ़ंक्शन में अनुक्रमित कॉलम को 'छिपाएँ' नहीं, जैसे कि WHERE DATE(x) = ...
; WHERE x = ...
रूप में सुधार
आप एक उपयुक्त WHERE LCASE(name1) = LCASE(name2)
होने से आमतौर पर WHERE LCASE(name1) = LCASE(name2)
से बच सकते हैं।
"पेजिनेशन" के लिए OFFSET
उपयोग न करें, इसके बजाय 'याद रखें कि आपने कहां छोड़ा था'।
SELECT * ...
बचें SELECT * ...
(जब तक डिबगिंग नहीं)।
मारिया डेलेवा, बैरेंका, बट्सू पर ध्यान दें: यह एक स्थान धारक है; जब आप पूर्ण पैमाने पर उदाहरण बनाते हैं तो कृपया इन वस्तुओं को हटा दें। आपके द्वारा किए जाने के बाद, मैं बाकी हिस्सों पर विस्तार करने और / या उन्हें टॉस करने के लिए आगे बढ़ूंगा।
नकारात्मक
यहां कुछ चीजें दी गई हैं जो प्रदर्शन में मदद करने की संभावना नहीं हैं। वे पुरानी जानकारी और / या भोलेपन से उपजी हैं।
- InnoDB उस बिंदु तक बेहतर हो गया है जहां MyISAM के बेहतर होने की संभावना नहीं है।
-
PARTITIONing
शायद ही कभी प्रदर्शन लाभ प्रदान करता है; यह प्रदर्शन को भी चोट पहुँचा सकता है। - 100 मीटर से बड़ा
query_cache_size
आमतौर पर प्रदर्शन को नुकसान पहुंचाएगा । - में मूल्यों के बहुत सारे बढ़ाने से
my.cnf
'अदला-बदली' है, जो एक गंभीर प्रदर्शन समस्या है हो सकता है। - "उपसर्ग सूचकांक" (जैसे
INDEX(foo(20))
) आम तौर पर बेकार हैं। -
OPTIMIZE TABLE
लगभग हमेशा बेकार है। (और इसमें टेबल को लॉक करना शामिल है।)
कोई INDEX हो
किसी भी गैर-छोटे टेबल पर क्वेरी को तेज करने के लिए सबसे महत्वपूर्ण बात एक उपयुक्त सूचकांक होना है।
WHERE a = 12 --> INDEX(a)
WHERE a > 12 --> INDEX(a)
WHERE a = 12 AND b > 78 --> INDEX(a,b) is more useful than INDEX(b,a)
WHERE a > 12 AND b > 78 --> INDEX(a) or INDEX(b); no way to handle both ranges
ORDER BY x --> INDEX(x)
ORDER BY x, y --> INDEX(x,y) in that order
ORDER BY x DESC, y ASC --> No index helps - because of mixing ASC and DESC
फ़ंक्शन में छिपाएँ नहीं
एक सामान्य गलती एक फ़ंक्शन कॉल के अंदर एक अनुक्रमित कॉलम को छिपाना है। उदाहरण के लिए, यह एक सूचकांक द्वारा मदद नहीं की जा सकती है:
WHERE DATE(dt) = '2000-01-01'
इसके बजाय, INDEX(dt)
तो ये सूचकांक का उपयोग कर सकते हैं:
WHERE dt = '2000-01-01' -- if `dt` is datatype `DATE`
यह DATE
, DATETIME
, TIMESTAMP
और यहां तक कि DATETIME(6)
(माइक्रोसेकंड) के लिए काम करता है:
WHERE dt >= '2000-01-01'
AND dt < '2000-01-01' + INTERVAL 1 DAY
या
सामान्य रूप से OR
अनुकूलन को मारता है।
WHERE a = 12 OR b = 78
INDEX(a,b)
उपयोग नहीं कर सकते हैं, और INDEX(a), INDEX(b)
"इंडेक्स मेरिट" के माध्यम से कर सकते हैं या नहीं भी कर सकते हैं। इंडेक्स मर्ज कुछ भी नहीं से बेहतर है, लेकिन केवल मुश्किल से।
WHERE x = 3 OR x = 5
में बदल गया है
WHERE x IN (3, 5)
जो इसमें x
साथ एक इंडेक्स का उपयोग कर सकता है।
सबक्वेरी
उपश्रेणियाँ कई स्वादों में आती हैं, और उनमें अलग-अलग अनुकूलन क्षमता होती है। सबसे पहले, ध्यान दें कि उपश्रेणियाँ "सहसंबद्ध" या "असंबद्ध" हो सकती हैं। सहसंबंधित का अर्थ है कि वे उपशम के बाहर से कुछ मूल्य पर निर्भर करते हैं। यह आमतौर पर तात्पर्य है कि प्रत्येक बाहरी मूल्य के लिए उप-वर्ग का पुनर्मूल्यांकन किया जाना चाहिए।
यह सहसंबद्ध उपशम अक्सर बहुत अच्छा होता है। नोट: इसे अधिकतम 1 मान पर लौटना चाहिए। यह अक्सर एक विकल्प के रूप में उपयोगी है, हालांकि जरूरी नहीं कि एक तेजी से LEFT JOIN
।
SELECT a, b, ( SELECT ... FROM t WHERE t.x = u.x ) AS c
FROM u ...
SELECT a, b, ( SELECT MAX(x) ... ) AS c
FROM u ...
SELECT a, b, ( SELECT x FROM t ORDER BY ... LIMIT 1 ) AS c
FROM u ...
यह आमतौर पर असंबंधित है:
SELECT ...
FROM ( SELECT ... ) AS a
JOIN b ON ...
FROM-SELECT
पर नोट्स:
- यदि यह 1 पंक्ति देता है, तो बढ़िया है।
- एक अच्छा प्रतिमान (फिर से "1 पंक्ति") के
( SELECT @n := 0 )
होने के लिए है( SELECT @n := 0 )
, जिससे बाकी या क्वेरी में उपयोग के लिए एक `( SELECT @n := 0 )
प्रारंभ करना। - यदि यह कई पंक्तियों को वापस करता है और
JOIN
भी है( SELECT ... )
कई पंक्तियों के साथ, तो दक्षता भयानक हो सकती है। पूर्व 5.6, कोई सूचकांक नहीं था, इसलिए यह एकCROSS JOIN
बन गया; 5.6+ अस्थायी टेबल पर सबसे अच्छा सूचकांक बात का अनुमान लगाना शामिल है और उसके बाद पैदा यह केवल इसे फेंक करने के लिए जब साथ समाप्तSELECT
।
JOIN + ग्रुप द्वारा
एक सामान्य समस्या जो एक अकुशल क्वेरी की ओर ले जाती है वह कुछ इस तरह से होती है:
SELECT ...
FROM a
JOIN b ON ...
WHERE ...
GROUP BY a.id
सबसे पहले, JOIN
पंक्तियों की संख्या का विस्तार करता है; इसके बाद GROUP BY
बीट सीटी इसे वापस पंक्तियों की संख्या में a
।
इस विस्फोट-प्रत्यारोपण समस्या को हल करने के लिए कोई अच्छा विकल्प नहीं हो सकता है। एक संभावित विकल्प को चालू करने के लिए है JOIN
में एक सहसंबद्ध सबक्वेरी में SELECT
। यह GROUP BY
को भी समाप्त करता है।