2008-09-18 6 views
17

क्या यह विशेष रूप से खराब है, बहुत सारे SQL संभावित क्वेरी के साथ बहुत से (संभवतः अनावश्यक) खंडों के साथ?एसक्यूएल क्वेरी (विशेष रूप से MySQL) की लंबाई तक प्रैक्टिकल सीमा

उदाहरण के लिए, यहाँ एक प्रश्न मैं अपने वेब एप्लिकेशन से जेनरेट किया है सब कुछ के साथ बंद कर दिया है, जो सबसे बड़ा संभव क्वेरी इस कार्यक्रम उत्पन्न करने के लिए के लिए होना चाहिए:

SELECT * 
FROM 4e_magic_items 
INNER JOIN 4e_magic_item_levels 
    ON 4e_magic_items.id = 4e_magic_item_levels.itemid 
INNER JOIN 4e_monster_sources 
    ON 4e_magic_items.source = 4e_monster_sources.id 
WHERE (itemlevel BETWEEN 1 AND 30) 
    AND source!=16 AND source!=2 AND source!=5 
    AND source!=13 AND source!=15 AND source!=3 
    AND source!=4 AND source!=12 AND source!=7 
    AND source!=14 AND source!=11 AND source!=10 
    AND source!=8 AND source!=1 AND source!=6 
    AND source!=9 AND type!='Arms' AND type!='Feet' 
    AND type!='Hands' AND type!='Head' 
    AND type!='Neck' AND type!='Orb' 
    AND type!='Potion' AND type!='Ring' 
    AND type!='Rod' AND type!='Staff' 
    AND type!='Symbol' AND type!='Waist' 
    AND type!='Wand' AND type!='Wondrous Item' 
    AND type!='Alchemical Item' AND type!='Elixir' 
    AND type!='Reagent' AND type!='Whetstone' 
    AND type!='Other Consumable' AND type!='Companion' 
    AND type!='Mount' AND (type!='Armor' OR (false)) 
    AND (type!='Weapon' OR (false)) 
ORDER BY type ASC, itemlevel ASC, name ASC 

ऐसा लगता है काफी अच्छी तरह से काम करने के लिए, लेकिन यह विशेष रूप से उच्च यातायात नहीं है (दिन में कुछ सौ हिट), और मुझे आश्चर्य है कि क्या यह अनावश्यकताओं को हटाने के लिए प्रश्नों को आजमाने और अनुकूलित करने के प्रयास के लायक होगा।

+0

1. सवाल का जवाब देने के लिए धन्यवाद है यह केवल वास्तविक सीमा एक सर्वर पर यह समायोज्य है, मुझे लगता है कि क्वेरी का आकार अब मेरे लिए कोई समस्या नहीं होनी चाहिए। 2. SQL को स्वरूपित करने के सुझावों के लिए सभी को धन्यवाद। मैं इसके लिए नया हूं और वहां बहुत सारी चालें हैं जिन्हें मैं नहीं जानता (उदाहरण के लिए "टाइप न करें (...)") 3. बस एक परिशिष्ट के रूप में, यह एक PHP/MySQL ऐप – Asmor

+1

यहां उपयोगी है ऑनलाइन एसक्यूएल फॉर्मेटर: http://www.sqlinform.com/ – micahwittman

+0

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

उत्तर

19

आपकी क्वेरी पढ़ना मुझे आरपीजी खेलना चाहता है।

यह निश्चित रूप से बहुत लंबा नहीं है। जब तक वे अच्छी तरह से स्वरूपित होते हैं, मैं कहूंगा कि एक व्यावहारिक सीमा लगभग 100 लाइनें है। इसके बाद, आप अपनी आंखों को पार करने से रोकने के लिए विचारों को तोड़ने से बेहतर होते हैं।

मैंने कुछ प्रश्नों के साथ काम किया है जो 1000+ लाइनें हैं, और इसे डीबग करना मुश्किल है।

वैसे, क्या मैं एक सुधारित संस्करण सुझा सकता हूं? यह ज्यादातर स्वरूपण के महत्व को प्रदर्शित करने के लिए है; मुझे विश्वास है कि यह समझना आसान होगा।

select * 
from 
    4e_magic_items mi 
,4e_magic_item_levels mil 
,4e_monster_sources ms 
where mi.id = mil.itemid 
    and mi.source = ms.id 
    and itemlevel between 1 and 30 
    and source not in(16,2,5,13,15,3,4,12,7,14,11,10,8,1,6,9) 
    and type not in(
        'Arms' ,'Feet' ,'Hands' ,'Head' ,'Neck' ,'Orb' , 
        'Potion' ,'Ring' ,'Rod' ,'Staff' ,'Symbol' ,'Waist' , 
        'Wand' ,'Wondrous Item' ,'Alchemical Item' ,'Elixir' , 
        'Reagent' ,'Whetstone' ,'Other Consumable' ,'Companion' , 
        'Mount' 
       ) 
    and ((type != 'Armor') or (false)) 
    and ((type != 'Weapon') or (false)) 
order by 
    type asc 
,itemlevel asc 
,name asc 

/* 
Some thoughts: 
============== 
0 - Formatting really matters, in SQL even more than most languages. 
1 - consider selecting only the columns you need, not "*" 
2 - use of table aliases makes it short & clear ("MI", "MIL" in my example) 
3 - joins in the WHERE clause will un-clutter your FROM clause 
4 - use NOT IN for long lists 
5 - logically, the last two lines can be added to the "type not in" section. 
    I'm not sure why you have the "or false", but I'll assume some good reason 
    and leave them here. 
*/ 
+1

असल में चीजों को गति देगा, खासकर उचित सूचकांक के साथ। कारण यह है कि यदि आपके सभी खंड कहां हैं, तो mysql सभी डेटा लाएगा, और उसके बाद इसे फ़िल्टर करेगा; जबकि एक उचित जुड़ाव के साथ यह केवल आवश्यक डेटा का चयन करेगा, जो कि छोटे पैमाने पर कुछ आदेश हो सकता है - फ़िल्टर करने के लिए तेज़। – Aeon

+1

ओह, और ... जब तक मैं कुछ, याद कर रहा हूँ (प्रकार! = 'कवच' या (गलत)) या तो सही या गलत पर मूल्यांकन करने के लिए जा रहा है, लेकिन या तो मामले में यह करने के लिए नहीं जा रहा है परिणाम सेट को प्रभावित करें, इसलिए यह वास्तव में भी आवश्यक नहीं है। – Aeon

+1

ऐसा इसलिए है क्योंकि कवच (और हथियारों) को प्रकार के द्वारा फ़िल्टर किया जाता है। तो उदाहरण के लिए, यदि कपड़ा और छिपे हुए चुने गए हैं, तो यह पढ़ेगा: (टाइप! = 'आर्मर' या ('सी' या 'एच' जैसे प्रतिबंध या प्रतिबंध)) पृष्ठ बस "या कुछ भी 'जैसे प्रतिबंध जोड़ता है "माता-पिता के अंदर, इतनी झूठी जरूरत है। – Asmor

0

अधिकांश डेटाबेस इस समस्या से बचने के लिए संग्रहीत प्रक्रियाओं का समर्थन करते हैं। यदि आपका कोड निष्पादित करने के लिए पर्याप्त तेज़ और पढ़ने में आसान है, तो आप संकलन समय को कम करने के लिए इसे बदलना नहीं चाहते हैं।

एक वैकल्पिक ताकि आप ग्राहक कनेक्शन के प्रति केवल एक बार हिट मिल तैयार बयानों उपयोग करने के लिए और उसके बाद प्रत्येक कॉल

15

डिफ़ॉल्ट MySQL 5.0 सर्वर सीमा "1 एमबी", अप करने के लिए विन्यास योग्य है के लिए में केवल पैरामीटर पास है 1GB।

यह क्लाइंट और सर्वर दोनों पर max_allowed_packet सेटिंग के माध्यम से कॉन्फ़िगर किया गया है, और प्रभावी सीमा दोनों का पाठक है।

चेतावनियां:

  • यह संभावना है कि इस "पैकेट" सीमा एक एसक्यूएल बयान में पात्रों के लिए सीधे नक्शा नहीं है। निश्चित रूप से आप क्लाइंट के भीतर खाता एन्कोडिंग, कुछ पैकेट मेटाडेटा, आदि में लेना चाहते हैं)
0

मुझे लगता है कि आप 'बंद' से मतलब है कि किसी फ़ील्ड का कोई मूल्य नहीं है?

यह जांचने के बजाय कि कुछ ऐसा नहीं है, और यह भी नहीं है आदि। क्या आप यह जांच नहीं सकते कि फ़ील्ड शून्य है या नहीं? या फ़ील्ड को 'ऑफ' पर सेट करें, और जांचें कि क्या टाइप या जो भी 'ऑफ' बराबर है।

1

एक व्यावहारिक परिप्रेक्ष्य से, मैं आम तौर पर किसी भी चयन पर विचार करता हूं जो लिखने के लिए 10 से अधिक लाइनों को लेता है (प्रत्येक खंड/शर्त को एक अलग रेखा पर डालकर) आसानी से बनाए रखने के लिए बहुत लंबा होता है। इस बिंदु पर, इसे शायद किसी प्रकार की संग्रहीत प्रक्रिया के रूप में किया जाना चाहिए, या मुझे एक ही अवधारणा को व्यक्त करने का एक बेहतर तरीका खोजने की कोशिश करनी चाहिए - संभवत: एक रिश्ते को पकड़ने के लिए इंटरमीडिएट टेबल बनाकर मुझे अक्सर पूछताछ की जा रही है।

आपका माइलेज भिन्न हो सकता है, और कुछ असाधारण लंबे प्रश्न हैं जिनके पास एक अच्छा कारण है। लेकिन अंगूठे का मेरा नियम 10 लाइन है।

उदाहरण (हल्का अनुचित एसक्यूएल):

SELECT x, y, z 
FROM a, b 
WHERE fiz = 1 
AND foo = 2 
AND a.x = b.y 
AND b.z IN (SELECT q, r, s, t 
      FROM c, d, e 
      WHERE c.q = d.r 
       AND d.s = e.t 
       AND c.gar IS NOT NULL) 
ORDER BY b.gonk 

यह शायद बहुत बड़ी है; अनुकूलन, हालांकि, संदर्भ पर काफी हद तक निर्भर करेगा।

बस याद रखें, प्रश्न जितना लंबा और अधिक जटिल होगा, उतना ही कठिन बनाएगा।

3

चयन @@ global.max_allowed_packet

तो कोई वास्तविक सीधा जवाब

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