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

ऑप्टिमाइज़ क्वेरी (इंडेक्सिंग, एक्सप्लाइन) मैसकल

मैं इस शब्द को भूलता रहता हूं क्योंकि यह मेरे लिए बहुत ही कम आता है, लेकिन किसी भी तरह, आपकी अनुक्रमणिका को MONTH() और YEAR() का उपयोग करके अनुकूलित नहीं किया जा सकता क्योंकि वे अंतर्निहित डेटा पर कार्य करते हैं। दिनांक RANGE लागू करके, वे कर सकते हैं। इसलिए आप अपना महीना/वर्ष रख सकते हैं जैसे कि जनवरी 2021 में कुछ बनाया गया था और मार्च 2021 में अपडेट किया गया था, लेकिन इसके अलावा, एक "और c.date_created>=current_date और current_date <=c.date_updated" , आप इंडेक्स का उपयोग कर सकते हैं यदि इसमें बनाई गई तिथि है (इस मामले में अद्यतन तिथि के लिए कम महत्वपूर्ण है। इसी तरह आपकी अन्य तालिका के लिए।

इसके अलावा, जब आप "ए" से "सी" तालिका में अपना बायां-जुड़ाव करते हैं, तो जहां आवेदन करते हैं, यह लगभग ऐसा लगता है जैसे आप शामिल होने के लिए मजबूर करने की कोशिश कर रहे हैं लेकिन OR के कारण बाएं-जुड़े रहते हैं।

मैं "सी" आधारित स्थिति को बाएं-जुड़ने के लिए ले जाऊंगा, फिर केवल उस रिकॉर्ड के लिए परीक्षण करें जो न्यूल के रूप में मिला है या नहीं।

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

इसके अतिरिक्त, चूंकि महीना () और वर्ष () sargeable नहीं हैं। (धन्यवाद ओली), मैं चालू महीने की शुरुआत और अगले महीने की शुरुआत करने के लिए एक प्रीक्वेरी कर रहा हूं ताकि मैं एक का निर्माण कर सकूं

WHERE > beginning of this month and LESS than beginning of next month

जहां तक ​​अनुक्रमणिका का संबंध है, मैं

. के लिए अद्यतन करना प्रारंभ करूंगा/करूंगी
loan_applications_tbl ( date_created, date_updated, loan_status, current_loan, ippis )
topup_or_reapplication_tbl ( ippis, status, current_loan, date_created, date_updated )

कोशिश करने के लिए अंतिम क्वेरी।

SELECT 
        a.id, 
        a.user_unique_id, 
        a.loan_location, 
        a.ippis, 
        a.tel_no,
        a.organisation, 
        a.branch, 
        a.loan_agree, 
        a.loan_type, 
        a.appr, 
        a.sold, 
        a.loan_status, 
        a.top_up, 
        a.current_loan, 
        a.date_created, 
        a.date_updated, 
        c.loan_id, 
        c.user_unique_id tu_user_unique_id, 
        c.ippis tu_ippis, 
        c.top_up_approved,
        c.loan_type tu_loan_type, 
        c.dse, 
        c.status, 
        c.current_loan tu_current_loan,
        c.record_category, 
        c.date_created tu_date_created,
        c.date_updated tu_date_updated 
    FROM 
        -- this creates inline mySQL variables I can use for the WHERE condition
        -- by doing comma after with no explicit join, it is a single row
        -- and thus no Cartesian result, just @variables available now
        ( select 
                -- first truncating any TIME portion by casting to DATE()
                @myToday := date(curdate()),
                @howFarBack := date_sub( @myToday, interval 6 month ),
                -- now subtract day of month -1 to get first of THIS month
                @beginOfMonth := date_sub( @myToday, interval dayOfMonth( @myToday ) -1 day ),
                -- and now, add 1 month for beginning of next
                @beginNextMonth := date_add( @beginOfMonth, interval 1 month ) ) SqlVars,

        loan_applications_tbl a
    
            LEFT JOIN topup_or_reapplication_tbl c
                ON  a.ippis = c.ippis   
                AND c.current_loan='1'
                AND c.status IN ('pending', 'corrected', 'Rejected', 
                                'Processing', 'Captured', 'Reviewed', 'top up') 
                AND 
                (
                        (@beginOfMonth <= c.date_created 
                    AND c.date_created < @beginNextMonth)
        
                OR
                        (@beginOfMonth <= a.date_updated 
                    AND a.date_updated < @beginNextMonth )
                )

    WHERE
            -- forces only activity for the single month in question
            -- since the "a" table knows of any "updates" to the "C",
            -- its updated basis will keep overall restriction to any accounts

            -- updated within this month in question only
            -- testing specifically for created OR updated within the
            -- current month in question

        a.date_created >= @howFarBack
        AND
            (
                    (@beginOfMonth <= a.date_created 
                AND a.date_created < @beginNextMonth)
        
            OR
                    (@beginOfMonth <= a.date_updated 
                AND a.date_updated < @beginNextMonth )
            )
        
        -- and NOW we can easily apply the OR without requiring
        -- to run against the ENTIRE set of BOTH tables.
        AND (
                    c.ippis IS NOT NULL
                OR 
                    ( a.loan_status IN (  'pending', 'corrected', 'Rejected', 'Processing', 
                            'Captured', 'Reviewed', 'top up')
                    AND (   
                            a.current_loan = '1' 
                        OR  (   a.current_loan = '0' 
                            AND a.loan_status IN ('Approved', 'Closed')
                            )
                        )
                    )
            )

QUERY के लिए टिप्पणियाँ बंद करना

मैंने पहली तालिका पर क्वेरी और प्राथमिक अनुक्रमणिका को भी संशोधित किया है (प्रथम स्थान) रिकॉर्ड की बनाई गई तिथि। मैंने एक अतिरिक्त वेरिएबल @howFarBack भी जोड़ा है जो ऋण के लिए विचार करने के लिए अधिकतम बैकिंग टाइम है। मैंने 6 महीने पहले डिफॉल्ट किया था। क्या आपको ऋण के लिए 6 महीने से अधिक पुराने किसी खाते पर विचार करने की आवश्यकता होगी? या क्या "ए" खाता कुछ ऐसा रिकॉर्ड करता है जो 10 साल पीछे जा सकता है और शामिल करना चाहता है? मेरी धारणा है कि यह एक नया ऋण आवेदन जोड़ने की तिथि है। यदि ऐसा है, तो स्वीकृत होने, अंतिम रूप देने, रद्द करने से पहले 6 महीने पहले जाने की अनुमति देने से ऐतिहासिक रूप से कई महीनों के डेटा से गुजरना बंद हो जाएगा।

WHERE क्लॉज में, मैंने CREATED_DATE>=@howFarBack के लिए स्पष्ट ऐड जोड़ा। चाइल्ड रिकॉर्ड बनाना कभी भी संभव नहीं होगा, मूल जोड़ने की तारीख से पहले किसी भी समय अपडेट करना तो दूर की बात है। यह केवल चालू माह की गतिविधि या फॉरवर्ड को अर्हता प्राप्त करने के लिए बाध्य करेगा।

उदाहरण:28 अप्रैल को एक ऋण बनाएँ। तो क्वेरी चल रहा है, महीने की शुरुआत 1 अप्रैल है लेकिन 1 मई से कम है (यह 30 अप्रैल को 11:59:59 बजे शामिल करने की अनुमति देता है)

अब, हम मई में आते हैं और 4 मई को ऋण पर परिवर्तन किया जाता है। हम एक नए महीने में हैं और @howFarBack अभी भी दिसंबर 2020 तक पुराने एप्लिकेशन को पॉसिबल क्वालिफाई करने की अनुमति देता है बनाम उन एप्लिकेशन की पूरी तालिका जो 2005 तक वापस जा सकती हैं जो हम सभी जानते हैं। आप हमेशा सबसे वर्तमान डेटा के साथ रह रहे हैं और आप @howFarBack को अधिकतम बैकिंग टाइम के रूप में आसानी से बदल सकते हैं। इससे आपके प्रदर्शन की ज़रूरतों में मदद मिलनी चाहिए।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL क्वेरी जो आंशिक रकम की गणना करती है

  2. MySQL बड़े डेटाबेस से डुप्लिकेट को जल्दी से हटा देता है

  3. पायथन फ्लास्क और MySQL का उपयोग करके स्क्रैच से एक वेब ऐप बनाना:भाग 2

  4. एक्सेल स्प्रेडशीट या सीवीएस से MySQL में डेटा आयात करें

  5. MySQL पंक्ति नाम में php चर