Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

महंगी क्वेरी डेटाबेस सर्वर को नीचे ले जाती है - कम करने के तरीकों की तलाश

हम्म, मैं आपकी क्वेरी को इन पंक्तियों के साथ लिखने का प्रयास कर सकता हूं:

SELECT Sale_Item.deleted, Sale_Item.deleted_by,
       Sale_Item.sale_time, Sale_Item.sale_date,
       Sale_Item.comment,
       Sale_Item.payment_type,
       Sale_Item.customer_id,
       Sale_Item.employee_id,
       Sale_Item.category,
       Sale_Item.sale_id, Sale_Item.item_id, NULL as item_kit_id, Sale_Item.line, 
       Sale_Item.supplier_id,
       Sale_Item.serialnumber, Sale_Item.description,
       Sale_Item.quantity_purchased, Sale_Item.item_cost_price, Sale_Item.item_unit_price,
       Sale_Item.discount_percent,
       Sale_Item.lineSubtotal,
       Sale_Item.lineSubtotal * COALESCE(Tax.non_cumulative, 0) + (Sale_Item.lineSubtotal * COALESCE(Tax.non_cumulative, 0) + Sale_Item.non_cumulative) * COALESCE(Tax.cumulative, 0) AS lineTax,
       Sale_Item.lineSubtotal + (Sale_Item.lineSubtotal * COALESCE(Tax.non_cumulative, 0) + (Sale_Item.lineSubtotal * COALESCE(Tax.non_cumulative, 0) + Sale_Item.non_cumulative) * COALESCE(Tax.cumulative, 0)) AS lineTotal,
       Sale_Item.lineSubtotal - (Sale_Item.item_cost_price * Sale_Item.quantity_purchased) AS profit

FROM (SELECT Sale.deleted, Sale.deleted_by,
             Sale.sale_time, DATE(Sale.sale_time) AS sale_date,
             Sale.comment,
             Sale.payment_type,
             Sale.customer_id,
             Sale.employee_id,
             Item.category,
             Sale_Item.sale_id, Sale_Item.item_id, NULL as item_kit_id, Sale_Item.line, 
             Sale_Item.supplier_id,
             Sale_Item.serialnumber, Sale_Item.description,
             Sale_Item.quantity_purchased, Sale_Item.item_cost_price, Sale_Item.item_unit_price,
             Sale_Item.discount_percent,
             (Sale_Item.item_unit_price * Sale_Item.quantity_purchased) - (Sale_Item.item_unit_price * Sale_Item.quantity_purchased * Sale_Item.discount_percent / 100) as lineSubtotal                 
      FROM phppos_sales_items Sale_Item
      JOIN phppos_sales Sale
        ON Sale.sale_id = Sale_Item.sale_id
           AND Sale.sale_time >= TIMESTAMP('2014-04-01')
           AND Sale.sale_time < TIMESTAMPADD(MONTH, 1, '2014-04-01')
           AND Sale.location_id = 1
           AND Sale.store_account_payment = 0) Sale_Item

LEFT JOIN (SELECT Tax.sale_id, Tax.item_id, Tax.line,
                  SUM(CASE WHEN Tax.cumulative = 1 THEN Tax.percent ELSE 0 END) as cumulative,
                  SUM(CASE WHEN Tax.cumulative <> 1 THEN Tax.percent ELSE 0 END) as non_cumulative
           FROM phppos_sales_item_taxes Tax
           JOIN phppos_sales Sale
             ON Sale.sale_id = Tax.sale_id
                AND Sale.sale_time >= TIMESTAMP('2014-04-01')
                AND Sale.sale_time < TIMESTAMPADD(MONTH, 1, '2014-04-01')
                AND Sale.location_id = 1
                AND Sale.store_account_payment = 0
           GROUP BY Tax.sale_id, Tax.item_id, Tax.line) Tax
       ON Tax.sale_id = Sale_Item.sale_id
          AND Tax.item_id = Sale_Item.sale_id
          AND Tax.line =Sale_Item.line 

संगठनात्मक उद्देश्यों के लिए कई स्तंभों को स्थानांतरित किया। प्रसंस्करण समय पर इसका कोई बड़ा प्रभाव नहीं होना चाहिए।

मैंने phppos_suppliers . का संदर्भ हटा दिया है के रूप में:

  1. आप तालिका के किसी भी कॉलम का उपयोग नहीं करते हैं
  2. यह एक LEFT JOIN , जिसका अर्थ है कि आपको वहां पंक्तियों के मौजूद रहने की आवश्यकता नहीं है।

मैंने GROUP BY को स्थानांतरित कर दिया है एक नई सबक्वेरी में, क्योंकि phppos_sales_item_taxes एकमात्र तालिका है जिसमें दिए गए मानदंडों के लिए डुप्लिकेट पंक्तियां हो सकती हैं। मैंने phppos_sales . का संदर्भ शामिल किया है क्योंकि मुझे यकीन नहीं है कि MySQL का अनुकूलक (या कोई भी, वास्तव में) साइटरिया को नीचे धकेलने के लिए पर्याप्त स्मार्ट है।

क्वेरी के मुख्य भाग को सबक्वेरी में स्थानांतरित कर दिया गया है, इसलिए मुझे lineSubtotal के लिए फॉर्मूला टाइप करने की आवश्यकता नहीं होगी कई बार। मैंने पूरे फ़ॉर्मूले का उपयोग किया है, लेकिन सरलीकृत संस्करण उपलब्ध हैं:

Sale_Item.item_unit_price * Sale_Item.quantity_purchased * (1 - (Sale_Item.discount_percent / 100)) as lineSubtotal  

Sale_Item.lineSubtotal * COALESCE(Tax.non_cumulative + Tax.cumulative + Tax.non_cumulative * Tax.cumulative, 0) as Tax

.... आपको इन्हें लेखांकन द्वारा चलाना पड़ सकता है, हालांकि, क्योंकि वे संचालन के क्रम के बारे में (समझ में) स्पर्श करते हैं। यह हो सकता है एक तेज रनटाइम में परिणाम लेकिन मुझे शक है; अधिकतर यह शर्तों को और अधिक पठनीय बनाने के लिए सरलीकरण के बारे में है।

आपने क्वेरी के दूसरे भाग के लिए कोई टेबल लेआउट प्रदान नहीं किया, लेकिन मुझे लगता है कि यह समान है। संबंधित संशोधन पाठक के लिए एक अभ्यास के रूप में छोड़ दिया गया है।

सामान्य शमन रणनीतियां

क्वेरी को बदलने वाले किसी भी संभावित स्पीडअप से परे, समस्या को कम करने के लिए आप कई चीजें कर सकते हैं:

  1. अपनी आवेदन परत में, इस क्वेरी (और संभवतः अन्य) को नौकरी जमा करने की प्रक्रिया से गुजरने के लिए बाध्य करें, जिसके परिणाम बाद में प्राप्त किए जा सकते हैं। इस क्वेरी की नई कॉपी तब तक नहीं चलाई जा सकती, जब तक कि पिछली क्वेरी पूरी न हो जाए. मुझे लगता है कि PHP के पास इसके लिए एक मौजूदा पुस्तकालय है। सामान्य रूप से केवल थ्रॉटलिंग सबमिशन की आपको आवश्यकता हो सकती है।
  2. पुनर्प्राप्त किया जा रहा डेटा कैशिंग के लिए उत्तरदायी प्रतीत होता है - नवीनतम संसाधित sale_date से पहले सब कुछ संग्रहीत करें , और उसके बाद ही ऑन-द-फ्लाई नई जानकारी प्राप्त करें (हालांकि रूपांतरण वास्तव में इतना भिन्न नहीं है मूल से - हालांकि, अधिक जॉइन न करने से मदद मिल सकती है)।
  3. प्रसंस्करण की वर्तमान समयावधि में प्रश्नों की अनुमति न दें। यह सिस्टम को उन पंक्तियों तक पहुँचने का प्रयास करने से रोकना चाहिए जो अभी तक प्रतिबद्ध नहीं हैं, और संभावित रूप से संशोधन के तहत अनुक्रमणिका पृष्ठों से दूर हैं। यदि आपका संग्रहण समवर्ती I/O का लाभ उठाने के लिए निर्धारित किया गया है तो इस प्रकार की चाल सबसे अच्छा काम करती है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Neo4j ब्राउज़र

  2. एसक्यूएल:प्रत्येक कॉलम में अलग-अलग मानों की संख्या गिनें

  3. पॉलिमॉर्फिक टेबल पर कॉलम द्वारा लारवेल ऑर्डर परिणाम

  4. एक अलग कनेक्शन.php फ़ाइल का उपयोग करके mysqli क्वेरी का उपयोग कैसे करें?

  5. MySQL कंसोल विशाल SQL फ़ाइलों के आयात पर धीमा