2011-03-11 19 views

उत्तर

10

सवाल 44,917 में स्वीकार किए जाते हैं जवाब से खींचा के रूप में:

प्रदर्शन बुद्धिमान, वे वास्तव में कर रहे हैं ही (कम से कम एसक्यूएल सर्वर में), लेकिन बारे में पता होना है कि वे अंतर्निहित बाहरी वाक्य रचना में शामिल होने का बहिष्कार कर रहे हैं ।

MySQL में परिणाम समान हैं।

मैं व्यक्तिगत रूप से तालिकाओं में शामिल होने के साथ व्यक्तिगत रूप से रहूंगा ... यह करने का "सामाजिक स्वीकार्य" तरीका है।

+0

मुझे ओरेकल के लिए एक ही जवाब मिला, और कुछ सहमत हैं कि निष्पादन के लिए कोई अंतर नहीं है। ओरेकल के लिए क्वेरी के लिए "योजना" का निरीक्षण करने का एक तरीका है, क्या MySQL में कुछ समान है? – Victor

+0

यह आपके सॉफ्टवेयर पर निर्भर करता है। MySQL के लिए आप क्या उपयोग कर रहे हैं ... MySQL के लिए टोड में आपके द्वारा बनाई गई किसी भी क्वेरी के लिए "योजना समझाएं" टैब है, लेकिन संभवतः यह बिल्कुल नहीं है कि आप क्या खोज रहे हैं। यह "EXPLAIN" कमांड का उपयोग करता है जिसे ईवान ने अपने जवाब में उल्लेख किया है। – Patrick

+0

मैं मानता हूं कि स्पष्ट जॉइन बेहतर है। यह वास्तव में अधिक सुरक्षित है, और यदि आप WHERE क्लॉज का कुछ हिस्सा भूल जाते हैं तो क्रॉस जॉइन बनने के लिए कम प्रवण होता है। –

0

फोरम क्लॉज में कॉमा एक क्रॉस जॉइन है। हम कल्पना कर सकते हैं कि SQL सर्वर में एक चुनिंदा क्वेरी निष्पादन प्रक्रिया है जो किसी भी तरह दिखनी चाहिए: 1. प्रत्येक तालिका के माध्यम से पुनरावृत्त करें 2. पंक्तियों को ढूंढें जो भविष्य में शामिल होने से मिलते हैं और परिणाम तालिका में डालते हैं। 3. परिणाम तालिका से, केवल उन पंक्तियों को प्राप्त करें जो कहां से मिलते हैं।

यदि यह वास्तव में ऐसा लगता है, तो उस तालिका पर क्रॉस जॉइन का उपयोग करके कुछ हजार पंक्तियां आवंटित हो सकती हैं, जब प्रत्येक पंक्ति एक दूसरे के साथ संयुक्त हो जाती है, जहां स्थिति की जांच की जाती है। आपका SQL सर्वर तब काफी व्यस्त हो सकता है।

+0

की dup मैं इसे इस तरह से काम करता है नहीं लगता। यदि हां, तो क्या स्थिति है जहां पहली शर्त पहली तालिका को केवल एक रिकॉर्ड में फ़िल्टर करती है, तो यह केवल दूसरी तालिका के साथ एक रिकॉर्ड को जोड़ती है, जिससे यह वास्तव में तेज़ हो जाती है? मेरा मानना ​​है कि एसक्यूएल अन्य तरीकों से डेटा संभालता है (जिसे मैं केवल अनुमान लगा सकता हूं)। – dxvargas

0

मुझे ऐसा लगता है क्योंकि पहला उदाहरण स्पष्ट रूप से mysql को बताता है कि कौन से कॉलम शामिल हों और उनसे कैसे जुड़ें, जहां दूसरे एक mysql को यह पता लगाना है कि आप कहां शामिल होना चाहते हैं।

0

दूसरी क्वेरी एक आंतरिक जुड़ने के लिए सिर्फ एक और संकेत है, इसलिए अगर पोरफॉर्मेंस में कोई अंतर होता है तो यह केवल इसलिए होता है क्योंकि एक प्रश्न दूसरे की तुलना में तेज़ी से पार्स किया जा सकता है - और यह अंतर, यदि यह मौजूद है, तो यह बहुत छोटा होगा कि आप इसे नोटिस नहीं करेंगे।

अधिक जानकारी के लिए

आप this question पर एक नज़र (और एक सवाल है कि पहले से ही उत्तर है पूछ से पहले ताकि अगली बार पर खोज का उपयोग करें)

1

असल में वे वस्तुतः एक ही हैं की कोशिश कर सकते, शामिल हों/चालू है नया एएनएसआई सिंटैक, WHERE पुराना एएनएसआई सिंटैक्स है। दोनों को क्वेरी इंजन

0

पहली क्वेरी MySQL के लिए समझना आसान है, इसलिए यह संभव है कि निष्पादन योजना बेहतर रहेगी और क्वेरी तेज हो जाएगी।

जहां खंड के बिना दूसरी क्वेरी, एक क्रॉस शामिल है। यदि MySQL यह समझने में सक्षम है कि कौन सा खंड काफी अच्छा है, तो यह सभी पंक्तियों में शामिल होने से बचने के लिए सबसे अच्छा होगा, लेकिन कुछ भी इसकी गारंटी नहीं देता है।

आपके मामले जितना सरल होगा, प्रदर्शन सख्ती से समान होगा।

प्रदर्शन के अनुसार, पहली क्वेरी हमेशा बेहतर या दूसरी के समान होगी। और मेरे दृष्टिकोण से रीडिंग करते समय समझना भी बहुत आसान है।

10

वे वही हैं।,

 
mysql> explain Select * from Table1 T1 
    -> Inner Join Table2 T2 On T1.ID = T2.ID; 
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra          | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+ 
| 1 | SIMPLE  | T1 | index | PRIMARY  | PRIMARY | 4  | NULL | 4 | Using index         | 
| 1 | SIMPLE  | T2 | index | PRIMARY  | PRIMARY | 4  | NULL | 4 | Using where; Using index; Using join buffer | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+ 
2 rows in set (0.00 sec) 

mysql> explain Select * from Table1 T1, Table2 T2 
    -> Where T1.ID = T2.ID; 
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra          | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+ 
| 1 | SIMPLE  | T1 | index | PRIMARY  | PRIMARY | 4  | NULL | 4 | Using index         | 
| 1 | SIMPLE  | T2 | index | PRIMARY  | PRIMARY | 4  | NULL | 4 | Using where; Using index; Using join buffer | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+ 
2 rows in set (0.00 sec) 
2

खैर मुझ से एक देर से जवाब के रूप में मैं एक पुराने आवेदन का उपयोग करता है जो अल्पविराम आधारित INNER JOIN खंड के बजाय में शामिल होने के प्रदर्शन का विश्लेषण कर रहा हूँ: यह EXPLAIN आदेश चलाकर देखा जा सकता है।

तो यहां दो टेबल हैं जिनमें शामिल हैं (दोनों में 1 लाख से अधिक रिकॉर्ड हैं)। क्वेरी निष्पादित करते समय जिसमें अल्पविराम आधारित शामिल होता है, INNER JOIN मामले से बहुत अधिक समय लगता है।

जब मैंने समझाया गया बयान का विश्लेषण किया, तो मैंने पाया कि कॉमा में शामिल होने वाली क्वेरी में शामिल बफर का उपयोग किया गया था। हालांकि INNER JOIN खंड वाले प्रश्न 'कहां उपयोग कर रहे थे'।

यह प्रश्न भी काफी अलग हैं, जैसा कि पंक्तियों में कॉलम कॉलम में दिखाया गया है। ये मेरे प्रश्न और उनके संबंधित व्याख्या परिणाम हैं।

explain select count(*) FROM mbst a , his_moneypv2 b 
     WHERE b.yymm IN ('200802','200811','201001','201002','201003') 
     AND a.tel3 != '' 
     AND a.mb_no = b.mb_no 
     AND b.true_grade_class IN (3,6) 
     OR b.grade_class IN (4,7); 

+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+------+--------+---------------------------------------------------------------------+ 
| id | select_type | table | type  | possible_keys             | key         | key_len | ref | rows | Extra                | 
+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+------+--------+---------------------------------------------------------------------+ 
| 1 | SIMPLE  | b  | index_merge | PRIMARY,mb_no,yymm,yymm_2,idx_true_grade_class,idx_grade_class | idx_true_grade_class,idx_grade_class | 5,9  | NULL | 16924 | Using sort_union(idx_true_grade_class,idx_grade_class); Using where | 
| 1 | SIMPLE  | a  | ALL   | PRIMARY              | NULL         | NULL | NULL | 134472 | Using where; Using join buffer          | 
+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+------+--------+---------------------------------------------------------------------+ 

v/s

explain select count(*) FROM mbst a inner join his_moneypv2 b 
     on a.mb_no = b.mb_no 
     WHERE b.yymm IN ('200802','200811','201001','201002','201003') 
     AND a.tel3 != '' 
     AND b.true_grade_class IN (3,6) 
     OR b.grade_class IN (4,7); 

+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+--------------------+-------+---------------------------------------------------------------------+ 
| id | select_type | table | type  | possible_keys             | key         | key_len | ref    | rows | Extra                | 
+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+--------------------+-------+---------------------------------------------------------------------+ 
| 1 | SIMPLE  | b  | index_merge | PRIMARY,mb_no,yymm,yymm_2,idx_true_grade_class,idx_grade_class | idx_true_grade_class,idx_grade_class | 5,9  | NULL    | 16924 | Using sort_union(idx_true_grade_class,idx_grade_class); Using where | 
| 1 | SIMPLE  | a  | eq_ref  | PRIMARY              | PRIMARY        | 62  | shaklee_my.b.mb_no |  1 | Using where               | 
+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+--------------------+------ 
+1

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

+0

आपके प्रश्न समान पंक्तियां नहीं लौटाते हैं। 'B.grade_class IN (4,7) 'के साथ पंक्तियों में शामिल होने वाली क्रॉस हमेशा पहले से' से 'के आउटपुट में होती है, लेकिन जब' a.mb_no = b.mb_no' वे दूसरे 'से आउटपुट में नहीं होते हैं । तो प्रश्नों की तुलना करने से आप सवाल के बारे में कुछ नहीं बताते हैं। – philipxy

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