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

यदि तालिका में MySQL का उपयोग करके 10000 प्रविष्टियाँ हैं तो क्वेरी को कैसे अनुकूलित करें?

मैं आपकी अन्य तालिकाओं पर ट्रिगर्स डालकर, और आपके User_Fans तालिका में बस कुछ कॉलम जोड़कर इसे पूरी तरह से सरल बनाने की कोशिश करूंगा ... प्रत्येक संबंधित गणना के लिए एक () जिसे आप प्राप्त करने का प्रयास कर रहे हैं ... पोस्ट, पोस्टलाइक, पोस्टकॉमेंट्स से, पोस्ट कमेंट लाइक।

जब कोई रिकॉर्ड किसी भी तालिका में जोड़ा जाता है, तो गिनती में 1 जोड़ने के लिए बस अपनी user_fans तालिका को अपडेट करें ... यह किसी भी तरह उपयोगकर्ता की कुंजी आईडी के आधार पर लगभग तात्कालिक होगा। जहां तक ​​"LIKES" का सवाल है... इसी तरह, केवल इस शर्त के तहत कि कुछ "पसंद" के रूप में ट्रिगर होता है, 1 जोड़ें। "भारित" कुल मूल्य। जैसे-जैसे आपकी तालिका और भी बड़ी होती जाएगी, वैसे-वैसे क्वेरीज़ भी लंबी होती जाएंगी क्योंकि उनके पास डालने और एकत्र करने के लिए अधिक डेटा होगा। आप प्रत्येक उपयोगकर्ता_प्रशंसक रिकॉर्ड से गुजर रहे हैं जो संक्षेप में अन्य सभी तालिकाओं से प्रत्येक रिकॉर्ड को क्वेरी कर रहा है।

जो कुछ भी कहा जा रहा है, टेबल को आपके पास रखते हुए, मैं निम्नानुसार पुनर्गठन करूंगा...

SELECT 
      uf.user_name,
      uf.user_id,
      @pc := coalesce( PostSummary.PostCount, 000000 ) as PostCount,
      @pl := coalesce( PostLikes.LikesCount, 000000 ) as PostLikes,
      @cc := coalesce( CommentSummary.CommentsCount, 000000 ) as PostComments,
      @cl := coalesce( CommentLikes.LikesCount, 000000 ) as CommentLikes,
      @pc + @cc AS sum_post,
      @pl + @cl AS sum_like, 
      @pCalc := (@pc + @cc) * 10 AS post_cal,
      @lCalc := (@pl + @cl) * 5 AS like_cal,
      @pCalc + @lCalc AS `total`
   FROM
      ( select @pc := 0,
               @pl := 0,
               @cc := 0,
               @cl := 0,
               @pCalc := 0
               @lCalc := 0 ) sqlvars,
      user_fans uf
        LEFT JOIN ( select user_id, COUNT(*) as PostCount
                       from post
                       group by user_id ) as PostSummary
           ON uf.user_id = PostSummary.User_ID

        LEFT JOIN ( select user_id, COUNT(*) as LikesCount
                       from post_likes
                       group by user_id ) as PostLikes
           ON uf.user_id = PostLikes.User_ID

        LEFT JOIN ( select user_id, COUNT(*) as CommentsCount
                       from post_comment
                       group by user_id ) as CommentSummary
           ON uf.user_id = CommentSummary.User_ID

        LEFT JOIN ( select user_id, COUNT(*) as LikesCount
                       from post_comment_likes
                       group by user_id ) as CommentLikes
           ON uf.user_id = CommentLikes.User_ID

   ORDER BY 
      `total` DESC 
   LIMIT 20

My variables are abbreviated as 
"@pc" = PostCount
"@pl" = PostLikes
"@cc" = CommentCount
"@cl" = CommentLike
"@pCalc" = weighted calc of post and comment count * 10 weighted value
"@lCalc" = weighted calc of post and comment likes * 5 weighted value

प्रीक्वेरी में लेफ्ट जॉइन उन प्रश्नों को एक बार चलाता है, फिर प्रत्येक रिकॉर्ड के लिए उप-क्वेरी के रूप में हिट होने के बजाय पूरी चीज जुड़ जाती है। COALESCE() का उपयोग करके, यदि LEFT JOINed तालिका परिणामों में ऐसी कोई प्रविष्टियाँ नहीं हैं, तो आप कैल्क्स को गड़बड़ाने वाले NULL मानों से प्रभावित नहीं होंगे, इसलिए मैंने उन्हें 000000 पर डिफॉल्ट कर दिया है।

आपके प्रश्नों का स्पष्टीकरण

आपके पास "AS AliasResult" के रूप में कोई भी QUERY हो सकता है। सरल पठनीयता के लिए किसी भी लंबी तालिका के नाम को सरल बनाने के लिए "As" का भी उपयोग किया जा सकता है। उपनाम भी एक ही तालिका का उपयोग कर सकते हैं लेकिन समान सामग्री प्राप्त करने के लिए एक अलग उपनाम के रूप में, लेकिन अलग उद्देश्य के लिए।

select
      MyAlias.SomeField
   from
      MySuperLongTableNameInDatabase MyAlias ...

select
      c.LastName,
      o.OrderAmount
   from
      customers c
         join orders o
            on c.customerID = o.customerID  ...

select
      PQ.SomeKey
   from
      ( select ST.SomeKey
           from SomeTable ST
           where ST.SomeDate between X and Y ) as PQ
         JOIN SomeOtherTable SOT
            on PQ.SomeKey = SOT.SomeKey ...

अब, ऊपर दी गई तीसरी क्वेरी व्यावहारिक नहीं है (पूर्ण क्वेरी जिसके परिणामस्वरूप उपनाम "PQ" "PreQuery" का प्रतिनिधित्व करता है)। यह तब किया जा सकता है जब आप अन्य जटिल परिस्थितियों के एक निश्चित सेट को पूर्व-सीमित करना चाहते हैं और सभी अंतिम परिणामों के लिए कई अन्य तालिकाओं में अतिरिक्त जुड़ने से पहले एक छोटा सेट चाहते हैं।

चूंकि "FROM" का वास्तविक तालिका होना जरूरी नहीं है, लेकिन यह अपने आप में एक क्वेरी हो सकती है, क्वेरी में किसी अन्य स्थान का उपयोग किया जाता है, इसलिए इसे यह जानना होगा कि इस प्रीक्वेरी परिणामसेट को कैसे संदर्भित किया जाए।

साथ ही, जब फ़ील्ड की क्वेरी की जाती है, तो वे भी परिणामों को सरल बनाने के लिए "As FinalColumnName" हो सकते हैं, जहां कभी भी उनका उपयोग किया जाएगा।

CONCAT (उपयोगकर्ता। अभिवादन, उपयोगकर्ता। अंतिम नाम) को सौजन्य नाम के रूप में चुनें ...

SelectOrder.NonTaxable+ Order.Taxable+ ( Order.Taxable * Order.SalesTaxRate ) OrderTotalWithTaxfrom के रूप में ...

"अस" कॉलमनाम को एक समग्र होने की आवश्यकता नहीं है, लेकिन इसे आमतौर पर इस तरह देखा जाता है।

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

SQLVars के रूप में
select 
       ...
   from 
      ( select @SomeVar := 0,
               @SomeDate := curdate(),
               @SomeString := "hello" ) as SQLVars

अब, sqlvars कैसे काम करते हैं। एक लीनियर प्रोग्राम के बारे में सोचें... जैसे ही क्वेरी चलती है, एक कमांड को ठीक उसी क्रम में निष्पादित किया जाता है। उस मान को अगली बार के लिए तैयार "SQLVars" रिकॉर्ड में फिर से संग्रहीत किया जाता है। हालांकि, आप इसे SQLVars.SomeVar या SQLVars.SomeDate... बस @SomeVar:=someNewValue के रूप में संदर्भित नहीं करते हैं। अब, जब किसी क्वेरी में @var का उपयोग किया जाता है, तो इसे परिणाम सेट में "As ColumnName" के रूप में भी संग्रहीत किया जाता है। कभी-कभी, यह अगले रिकॉर्ड की तैयारी में केवल एक प्लेस-होल्डर परिकलित मूल्य हो सकता है। प्रत्येक मान तब अगली पंक्ति के लिए सीधे उपलब्ध होता है। तो, निम्नलिखित नमूना दिया गया...

select
      @SomeVar := SomeVar * 2 as FirstVal,
      @SomeVar := SomeVar * 2 as SecondVal,
      @SomeVar := SomeVar * 2 as ThirdVal
   from
      ( select @SomeVar := 1 ) sqlvars,
      AnotherTable
   limit 3

Will result in 3 records with the values of 

FirstVal    SecondVal   ThirdVal
2           4           8
16          32          64
128         256         512

ध्यान दें कि @SomeVar का मान कैसे उपयोग किया जाता है क्योंकि प्रत्येक कॉलम इसका उपयोग करता है ... तो उसी रिकॉर्ड पर भी, अद्यतन मान अगले कॉलम के लिए तुरंत उपलब्ध होता है ... उस ने कहा, अब एक सिम्युलेटेड रिकॉर्ड गिनती बनाने की कोशिश कर रहा है / प्रति ग्राहक रैंकिंग...

select
      o.CustomerID,
      o.OrderID
      @SeqNo := if( @LastID = o.CustomerID, @SeqNo +1, 1 ) as CustomerSequence,
      @LastID := o.CustomerID as PlaceHolderToSaveForNextRecordCompare
   from
      orders o,
      ( select @SeqNo := 0, @LastID := 0 ) sqlvars
   order by
      o.CustomerID

"ऑर्डर बाय" क्लॉज परिणामों को पहले क्रम में वापस करने के लिए मजबूर करता है। तो, यहां, प्रति ग्राहक रिकॉर्ड वापस कर दिए जाते हैं। पहली बार, LastID 0 है और ग्राहक ID कहलाती है...5। अलग होने के कारण, यह 1 को @SeqNo के रूप में लौटाता है, फिर यह उस ग्राहक आईडी को अगले रिकॉर्ड के लिए @LastID फ़ील्ड में सुरक्षित रखता है। अब, ग्राहक के लिए अगला रिकॉर्ड... अंतिम आईडी वही है, इसलिए यह @SeqNo (अब =1) लेता है, और 1 से 1 जोड़ता है और उसी ग्राहक के लिए #2 बन जाता है... पथ पर जारी रखें.. ।

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JDBC कनेक्शन त्रुटि:अपरिचित समयक्षेत्र

  2. ऑनलाइन MySql/Sql डेटाबेस के साथ Xamarin Android ऐप

  3. PHP में mysqli_query () का उपयोग कैसे करें?

  4. अंतिम MySQL विरासत डेटाबेस दुःस्वप्न

  5. MySQL में प्रत्येक श्रेणी के लिए शीर्ष 10 रिकॉर्ड का चयन करें