2011-11-21 13 views
11

मैं इस पर गौर किया है, लेकिन मैं अभी भी व्याख्या नहीं कर सकते क्यों MySQL क्वेरी है 115 एमएस बनाम 478 एमएमएस। वे दोनों InnoDB का उपयोग कर रहे हैं और संबंधों को परिभाषित किया गया है। 'Card_legality' में लगभग 200k पंक्तियां होती हैं, जबकि 'वैधता' तालिका में 11 पंक्तियां होती हैं।क्यों, में शामिल होने के लिए छोड़ दिया 'काफी' मेरे भीतर की तुलना में तेजी से शामिल हो

CREATE TABLE `card_legality` (
    `card_id` varchar(8) NOT NULL DEFAULT '', 
    `legality_id` int(3) NOT NULL, 
    `cl_boolean` tinyint(1) NOT NULL, 
    PRIMARY KEY (`card_id`,`legality_id`), 
    KEY `legality_id` (`legality_id`), 
    CONSTRAINT `card_legality_ibfk_2` FOREIGN KEY (`legality_id`) REFERENCES `legality` (`legality_id`), 
    CONSTRAINT `card_legality_ibfk_1` FOREIGN KEY (`card_id`) REFERENCES `card` (`card_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

और: यहाँ प्रत्येक के लिए संरचना है

CREATE TABLE `legality` (
    `legality_id` int(3) NOT NULL AUTO_INCREMENT, 
    `l_name` varchar(16) NOT NULL DEFAULT '', 
    PRIMARY KEY (`legality_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=latin1; 

मैं बस वाम-शामिल हों इस्तेमाल कर सकते हैं, लेकिन यह काफी सही है ... कोई विचार नहीं लगता है, कृपया?

अद्यतन: अनुरोध के अनुसार, मैंने प्रत्येक के लिए व्याख्या के परिणाम शामिल किए हैं। मैं यह पहले समाप्त हो चुकी थी, लेकिन मैं इसके बारे में एक पूरी तरह से समझने के लिए बहाना न ..

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE cl ALL PRIMARY NULL NULL NULL 199747 Using where 
1 SIMPLE l eq_ref PRIMARY PRIMARY 4 hexproof.co.uk.cl.legality_id 1 

और भीतरी में शामिल होने:

id select_type table type possible_keys key key_len   ref       rows Extra 
1 SIMPLE l ALL PRIMARY NULL NULL NULL 11 
1 SIMPLE cl ref PRIMARY,legality_id legality_id 4 hexproof.co.uk.l.legality_id 33799 Using where 
+0

जिस तरह से 'card_id' एक वर्चर है क्योंकि मेरे पास कोई विकल्प नहीं है, मैं आमतौर पर इसे स्वीकार नहीं करता। – Ben

उत्तर

9

यह card_id पर varchar के कारण है। MySQL कार्ड_आईडी पर इंडेक्स का उपयोग कार्ड_आईडी के रूप में नहीं कर सकता जैसा कि mysql type conversion वर्णित है। महत्वपूर्ण हिस्सा

है एक संख्या के साथ एक स्ट्रिंग स्तंभ की तुलना के लिए, MySQL जल्दी से मूल्य को देखने के लिए स्तंभ पर एक सूचकांक का उपयोग नहीं कर सकते हैं। यदि str_col अनुक्रमित स्ट्रिंग कॉलम है, तो निष्पादन करते समय इंडेक्स का उपयोग नहीं किया जा सकता है:

चुनें * tbl_name से str_col = 1;

इसका कारण यह है कि कई अलग-अलग तार हैं जो '1', '1', या '1a' जैसे मान 1 में परिवर्तित हो सकते हैं।

आप

SELECT cl.`cl_boolean`, l.`l_name` 
FROM `card_legality` cl 
INNER JOIN `legality` l ON l.`legality_id` = cl.`legality_id` 
WHERE cl.`card_id` = '23155' 

और

SELECT cl.`cl_boolean`, l.`l_name` 
FROM `card_legality` cl 
LEFT JOIN `legality` l ON l.`legality_id` = cl.`legality_id` 
WHERE cl.`card_id` = '23155' 

करने के लिए अपने प्रश्नों को बदलते हैं आप गति में एक विशाल सुधार देखना चाहिए और यह भी एक अलग व्याख्या देखते हैं।

यहाँ इस दिखाने के लिए एक समान है (लेकिन आसान) परीक्षा है:

> desc id_test; 
+-------+------------+------+-----+---------+-------+ 
| Field | Type  | Null | Key | Default | Extra | 
+-------+------------+------+-----+---------+-------+ 
| id | varchar(8) | NO | PRI | NULL |  | 
+-------+------------+------+-----+---------+-------+ 
1 row in set (0.17 sec) 

> select * from id_test; 
+----+ 
| id | 
+----+ 
| 1 | 
| 2 | 
| 3 | 
| 4 | 
| 5 | 
| 6 | 
| 7 | 
| 8 | 
| 9 | 
+----+ 
9 rows in set (0.00 sec) 

> explain select * from id_test where id = 1; 
+----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra     | 
+----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+ 
| 1 | SIMPLE  | id_test | index | PRIMARY  | PRIMARY | 10  | NULL | 9 | Using where; Using index | 
+----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+ 
1 row in set (0.00 sec) 


> explain select * from id_test where id = '1'; 
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ 
| 1 | SIMPLE  | id_test | const | PRIMARY  | PRIMARY | 10  | const | 1 | Using index | 
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ 
1 row in set (0.00 sec) 

पहले मामले में वहाँ Using where; Using index और दूसरा Using index है। इसके अलावा NULL या CONST भी रेफरी है। कहने की जरूरत नहीं है, दूसरा बेहतर है।

+0

आह! प्रतिभाशाली! आप सही हैं, 'कार्ड_आईडी' को एक आईएनटी के रूप में खोजते हैं, जब वास्तव में यह एक वर्चर था, तो ये प्रश्न लगभग 600x धीमे हो गए थे! धन्यवाद एंड्रियास :) – Ben

+0

हाँ। एंड्रियास धन्यवाद यहाँ बहुत अच्छी जानकारी। – stefgosselin

+0

मैंने एक लिंक जोड़ा है जहां यह समझाया गया है। यह अच्छी पढ़ाई है। –

3

मैं उन प्रश्नों के दोनों पर EXPLAIN कोशिश होगी। के साथ बस प्रत्येक SELECT उपसर्ग करें और उन्हें चलाएं। यह वास्तव में उपयोगी जानकारी देता है कि MySQL कैसे अनुकूलन और क्वेरी निष्पादित कर रहा है। कोई सबूत नहीं है इस समय इस बैकअप लेने के लिए -

+3

हाथ पर विषय के आधार पर मैं कहूंगा कि ओपी को "एक्सप्लाइन" का उपयोग करने के बारे में पता है कि एक बहुत बड़ा मौका है। किसी भी तरह से इस तरह की जानकारी को एक टिप्पणी में रखा जाना चाहिए और जवाब में नहीं, क्योंकि आप अपने प्रश्न का उत्तर देने का प्रयास नहीं कर रहे हैं। – Naatan

+0

हाय एल 2 जी, आपकी टिप्पणी के लिए धन्यवाद। मैं ** EXPLAIN ** फ़ंक्शन के साथ दृढ़ रहूंगा और देख सकता हूं कि मुझे क्या मिल सकता है। MySQL मैनुअल कुछ हद तक कमी है (या यह मेरे लिए कम से कम है)। बहुत धन्यवाद – Ben

0

मैं यकीन है कि वाम शामिल के लिए MySql बेहतर अनुकूलन है कि कर रहा हूँ।

ईटीए: एक त्वरित स्काउट दौर और मैं कुछ भी मेरे विचार तो बनाए रखने के लिए ठोस नहीं मिल सकता है .....

+0

धन्यवाद K.Bob, मैंने समान पढ़ा, लेकिन खुद की तरह; कोई प्रमाण नहीं मिला – Ben

2

L2G, यह बहुत ज्यादा अभिव्यक्त किया है, हालांकि मुझे लगता है यह varchar की वजह से हो सकता है card_id के लिए इस्तेमाल किया गया प्रकार।

मैं वास्तव में बाहर मुद्रित बेंच मार्किंग के लिए this informative page/लघु संभोग की रूपरेखा। यहां एक त्वरित गरीब-मानव प्रोफाइलिंग तकनीक है:

Time a SQL on MySQL 
Enable Profiling 
mysql> SET PROFILING = 1 
... 
RUN your SQLs 
... 
mysql> SHOW PROFILES; 

+----------+------------+-----------------------+ 
| Query_ID | Duration | Query     | 
+----------+------------+-----------------------+ 
|  1 | 0.00014600 | SELECT DATABASE()  | 
|  2 | 0.00024250 | select user from user | 
+----------+------------+-----------------------+ 
mysql> SHOW PROFILE for QUERY 2; 

+--------------------------------+----------+ 
| Status       | Duration | 
+--------------------------------+----------+ 
| starting      | 0.000034 | 
| checking query cache for query | 0.000033 | 
| checking permissions   | 0.000006 | 
| Opening tables     | 0.000011 | 
| init       | 0.000013 | 
| optimizing      | 0.000004 | 
| executing      | 0.000011 | 
| end       | 0.000004 | 
| query end      | 0.000002 | 
| freeing items     | 0.000026 | 
| logging slow query    | 0.000002 | 
| cleaning up     | 0.000003 | 
+--------------------------------+----------+ 

शुभकामनाएँ, ओह और कृपया अपने निष्कर्ष पोस्ट करें!

+0

यह वास्तव में उपयोगी जानकारी stefgosselin है, धन्यवाद। आपका पूर्वानुमान वास्तव में सही था, लेकिन एंड्रियास द्वारा स्पष्टीकरण ने इसे समझाया। आपकी मदद के लिए धन्यवाद :) – Ben

संबंधित मुद्दे