एक दूसरे के भीतर subqueries घोंसला द्वारा MySQL में 61 टेबल जॉइन सीमा के आसपास काम करें

I figured out that you can get around the 61 table join limit in MySQL by using subqueries. https://stackoverflow.com/a/20134402/2843690

मैं यह पता लगाने की कोशिश कर रहा हूं कि Magento से विस्तृत उत्पाद सूची प्राप्त करने के लिए मैं जिस प्रोग्राम पर काम कर रहा हूं, उसमें आसानी से इसका उपयोग कैसे करें (लेकिन मुझे लगता है कि इस प्रश्न का उत्तर बहुत से लागू हो सकता है स्थितियों जहां ईवी शामिल है)। जिन टेबलों को शामिल करने की आवश्यकता है, वे इस तरह कुछ दिखते हैं:

catalog_product_entity
+-----------+----------------+
| entity_id | entity_type_id |
+-----------+----------------+
|         1 |              4 |
|         2 |              4 |
|         3 |              4 |
|         4 |              4 |
|         5 |              4 |
|         6 |              4 |
|         7 |              4 |
|         8 |              4 |
|         9 |              4 |
+-----------+----------------+

catalog_product_entity_int
+----------+----------------+--------------+-----------+-------+
| value_id | entity_type_id | attribute_id | entity_id | value |
+----------+----------------+--------------+-----------+-------+
|        1 |              4 |            2 |         1 |   245 |
|        2 |              4 |            3 |         1 |   250 |
|        3 |              4 |            4 |         1 |   254 |
|        4 |              4 |            2 |         2 |   245 |
|        5 |              4 |            3 |         2 |   249 |
|        6 |              4 |            4 |         2 |   253 |
|        7 |              4 |            2 |         3 |   247 |
|        8 |              4 |            3 |         3 |   250 |
|        9 |              4 |            4 |         3 |   254 |
+----------+----------------+--------------+-----------+-------+

eav_attribute
+--------------+----------------+----------------+--------------+
| attribute_id | entity_type_id | attribute_code | backend_type |
+--------------+----------------+----------------+--------------+
|            1 |              4 | name           | varchar      |
|            2 |              4 | brand          | int          |
|            3 |              4 | color          | int          |
|            4 |              4 | size           | int          |
|            5 |              4 | price          | decimal      |
|            6 |              4 | cost           | decimal      |
|            7 |              4 | created_at     | datetime     |
|            8 |              3 | name           | varchar      |
|            9 |              3 | description    | text         |
+--------------+----------------+----------------+--------------+

eav_attribute_option
+-----------+--------------+
| option_id | attribute_id |
+-----------+--------------+
|       245 |            2 |
|       246 |            2 |
|       247 |            2 |
|       248 |            3 |
|       249 |            3 |
|       250 |            3 |
|       251 |            4 |
|       252 |            4 |
|       253 |            4 |
|       254 |            4 |
+-----------+--------------+

eav_attribute_option_value
+----------+-----------+-------------------+
| value_id | option_id |       value       |
+----------+-----------+-------------------+
|       15 |       245 | Fruit of the Loom |
|       16 |       246 | Hanes             |
|       17 |       247 | Jockey            |
|       18 |       248 | White             |
|       19 |       249 | Black             |
|       20 |       250 | Gray              |
|       21 |       251 | Small             |
|       22 |       252 | Medium            |
|       23 |       253 | Large             |
|       24 |       254 | Extra Large       |
+----------+-----------+-------------------+

जिस प्रोग्राम को मैं लिख रहा हूं वह एसक्यूएल प्रश्न उत्पन्न करता है जो इस तरह कुछ दिखता है:

SELECT cpe.entity_id
, brand_int.value as brand_int, brand.value as brand
, color_int.value as color_int, color.value as color
, size_int.value as size_int, size.value as size

FROM catalog_product_entity as cpe

LEFT JOIN catalog_product_entity_int as brand_int
ON (cpe.entity_id = brand_int.entity_id
AND brand_int.attribute_id = 2)
LEFT JOIN eav_attribute_option as brand_option
ON (brand_option.attribute_id = 2
AND brand_int.value = brand_option.option_id)
LEFT JOIN eav_attribute_option_value as brand
ON (brand_option.option_id = brand.option_id)

LEFT JOIN catalog_product_entity_int as color_int
ON (cpe.entity_id = color_int.entity_id
AND color_int.attribute_id = 3)
LEFT JOIN eav_attribute_option as color_option
ON (color_option.attribute_id = 3
AND color_int.value = color_option.option_id)
LEFT JOIN eav_attribute_option_value as color
ON (color_option.option_id = color.option_id)

LEFT JOIN catalog_product_entity_int as size_int
ON (cpe.entity_id = size_int.entity_id
AND size_int.attribute_id = 4)
LEFT JOIN eav_attribute_option as size_option
ON (size_option.attribute_id = 4
AND size_int.value = size_option.option_id)
LEFT JOIN eav_attribute_option_value as size
ON (size_option.option_id = size.option_id)
;

क्वेरी उत्पन्न करने के लिए कोड लिखना अपेक्षाकृत आसान था, और क्वेरी को समझने में काफी आसान था; हालांकि, 61 टेबल में शामिल होने वाली सीमा को हिट करना बहुत आसान है, जिसे मैंने अपने वास्तविक जीवन डेटा के साथ किया था। मेरा मानना ​​है कि गणित का कहना है कि 21 पूर्णांक-प्रकार गुण सीमा से अधिक हो जाएंगे, और इससे पहले कि मैं वर्चर, टेक्स्ट और दशमलव विशेषताओं को जोड़ना शुरू कर दूं।

तो जिस समाधान के साथ मैं आया था वह 61 टेबल सीमा को पार करने के लिए सबक्वायरीज़ का उपयोग करना था।

ऐसा करने का एक तरीका है 61 जोड़ों की उप-श्रेणियों में शामिल होना समूह। और फिर सभी समूह शामिल हो जाएंगे। मुझे लगता है कि मैं समझ सकता हूं कि एसक्यूएल प्रश्नों की तरह क्या दिखना चाहिए, लेकिन प्रश्न उत्पन्न करने के लिए कोड लिखना मुश्किल लगता है। अगर वहां पर्याप्त गुण थे तो एक और फिर भी (सैद्धांतिक) समस्या है कि एक व्यक्ति फिर से 61 टेबल सीमा का उल्लंघन कर सकता है। दूसरे शब्दों में, अगर मेरे पास 61 टेबल के 62 समूह हैं, तो एक MySQL त्रुटि होगी। जाहिर है, समूह के समूहों को 61 में समूहित करके कोई भी इसके आसपास हो सकता है। लेकिन यह कोड को लिखने और समझने के लिए और भी मुश्किल बनाता है।

मुझे लगता है कि मैं चाहता हूं कि समाधान सबक्वायरीज़ के भीतर घोंसला घोंसला करना है जैसे कि प्रत्येक सबक्वायरी 2 टेबल (या एक टेबल और एक सबक्वायरी) के एकल जुड़ने का उपयोग कर रही है। सहजता से, ऐसा लगता है कि कोड इस तरह की क्वेरी के लिए लिखना आसान होगा। दुर्भाग्यवश, यह सोचना कि इन प्रश्नों को कैसा दिखना चाहिए, यह मेरे दिमाग को चोट पहुंचा रहा है। यही कारण है कि मुझे मदद चाहिए।

ऐसी माईएसQL क्वेरी कैसी दिखती है?

3
जोड़ा संपादित
विचारों: 1
@ एक्सेल कैटलॉग_प्रॉडक्ट_फ्लैट को रीइन्डेक्स चालू होने की आवश्यकता है, मुझे विश्वास है। इसके अलावा catalog_product_flat में मेरी सारी जानकारी नहीं है। Magento संग्रह के लिए, मैं Magento के आंतरिक कार्यों से बहुत परिचित नहीं हूँ। और अब तक, मुझे सीधे MySQL प्रश्नों को Magento या api के उपयोग से काफी तेज़ पाया गया है।
जोड़ा लेखक The Phil Lee, स्रोत
इसके अलावा, मैं सिर्फ उत्सुक हूँ। भले ही यह इस मामले में व्यावहारिक नहीं है, यह बाद में कुछ के लिए उपयोगी हो सकता है। कम से कम, मुझे लगता है कि यह दिलचस्प हो सकता है।
जोड़ा लेखक The Phil Lee, स्रोत
यदि आपका प्राथमिक उद्देश्य "Magento से विस्तृत उत्पाद सूची प्राप्त करना" है, तो आप उन गुणों को शामिल क्यों नहीं करते हैं जिन्हें आप फ्लैट टेबल इंडेक्स में क्वेरी करना चाहते हैं, फिर बस चयन करें * catalog_product_flat_1 से चुनें ? या तो, या संग्रह बनाने के लिए मौजूदा Magento मॉडल का लाभ उठाएं, और उन विशेषताओं पर चयन करें जिन्हें आप प्रदर्शित करना चाहते हैं। आपका एसक्यूएल समाधान मेरी राय में एक अक्षम दृष्टिकोण है।
जोड़ा लेखक Axel, स्रोत
मुझे लगता है कि यह निर्भर करता है कि आपका लक्ष्य क्या है। यदि आप एक एक्सटेंशन बना रहे हैं, तो आपको मौजूदा तरीकों का लाभ उठाना चाहिए Magento इसके मूल मॉडल में प्रदान करता है। मैं Magento संग्रह का उपयोग करके सबकुछ पूछताछ करने की अनुशंसा करता हूं, फिर SQL Magento का उपयोग करके उत्पन्न करता है: $ संग्रह-> getSelect() -> ऑर्डर ('रैंड ()'); । यह आपको सभी विभिन्न डेटा एकत्र करने और इसे एक परिणाम परिणाम में संकलित करने के लिए Magento द्वारा उपयोग किया जाने वाला सटीक SQL दिखाएगा।
जोड़ा लेखक Axel, स्रोत

1 उत्तर

आप सही हैं कि ईएवी डिजाइन के माध्यम से बहुत से गुणों में शामिल होने से जुड़ने की सीमा से अधिक होने की संभावना है। इससे पहले भी, शायद जुड़ने की व्यावहारिक सीमा है क्योंकि इतने सारे जुड़ने की लागत उच्च और उच्चतर ज्यामितीय रूप से प्राप्त होती है। यह कितना बुरा है आपके सर्वर की क्षमता पर निर्भर करता है, लेकिन यह 61 से काफी कम होने की संभावना है।

तो एक परिणाम उत्पन्न करने के लिए एक ईएवी डेटा मॉडल से पूछताछ के रूप में जैसे कि यह एक पारंपरिक संबंध मॉडल (एक प्रति कॉलम प्रति विशेषता) में संग्रहीत किया गया है समस्याग्रस्त है।

समाधान: प्रति विशेषता में शामिल होने के साथ ऐसा न करें, जिसका अर्थ है कि आप परिणामस्वरूप एसक्यूएल के साथ पारंपरिक रूप से पारंपरिक पंक्ति-प्रति-इकाई प्रारूप में परिणाम उत्पन्न करने की उम्मीद नहीं कर सकते हैं।

मैं Magento स्कीमा से घनिष्ठ परिचित नहीं हूँ, लेकिन मैं आपकी क्वेरी से अनुमान लगा सकता हूं कि ऐसा कुछ काम कर सकता है:

SELECT cpe.entity_id
, o.value AS option
, v.value AS option_value
FROM catalog_product_entity AS cpe
INNER JOIN catalog_product_entity_int AS i 
  ON cpe.entity_id = i.entity_id AND i.attribute_id IN (2,3,4)
INNER JOIN eav_attribute_option AS o 
  ON i.value = o.option_id AND i.attribute_id = o.attribute_id
INNER JOIN eav_attribute_option_value AS v
  ON v.option_id = o.option_id;

IN (2,3,4, ...) predicate वह जगह है जहां आप एकाधिक विशेषताओं को निर्दिष्ट करते हैं। अधिक विशेषताओं को प्राप्त करने के लिए और अधिक जुड़ने की आवश्यकता नहीं है। वे कॉलम के बजाए पंक्तियों के रूप में वापस आ गए हैं।

इसका मतलब है कि आपको इस परिणाम सेट की सभी पंक्तियों को लाने के लिए एप्लिकेशन कोड लिखना होगा और उन्हें एक ऑब्जेक्ट के फ़ील्ड में मैप करना होगा।

@ एक्सेल द्वारा टिप्पणियों से, ऐसा लगता है कि Magento परिणाम सेट के उपभोग करने और इसे किसी ऑब्जेक्ट में मैप करने के लिए सहायक कार्यों प्रदान करता है।

2
जोड़ा
बिल्कुल वही नहीं जो मैं खोज रहा था, लेकिन वास्तव में इसे लागू करना बहुत आसान होगा। धन्यवाद। रिकॉर्ड के लिए, मैं अमेज़ॅन आरडीएस का उपयोग कर रहा हूं, और यहां तक ​​कि एक सूक्ष्म उदाहरण में 61-टेबल में शामिल होने के साथ-साथ 61 टेबलों की एक सबक्वायरी के साथ 61 टेबल की एक सबक्वायरी भी शामिल है) जहां तक ​​मैं कह सकता हूं। मुझे लगता है कि यह रिश्तेदार है, क्योंकि मैगेंटो या उसके एपीआई के माध्यम से समान प्रश्न करना हास्यास्पद रूप से धीमा है। इसके अलावा, मैंने MySQL लॉग के माध्यम से जो देखा है, उससे मैगेंटो आपके अधिक समझदार दृष्टिकोण नहीं लेता है और वास्तव में जटिल जॉइन के साथ-साथ इसके फ्लैट इंडेक्स टेब
जोड़ा लेखक The Phil Lee, स्रोत
इसके साथ मौलिक मुद्दा यह है कि यह केवल आईडी लौटाता है, न कि उन तालिकाओं के मूल्यों को जो इसमें शामिल होने की आवश्यकता है।
जोड़ा लेखक gshauger, स्रोत