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

SQL सर्वर के लिए सबसे तेज़ तरीका सम्मिलित करता है, अद्यतन करता है, चयन करता है

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

मेरे पास अपने डेटा स्तर में चुनिंदा प्रश्नों/प्रक्रियाओं के लिए एक सामान्य विधि है जो कुछ इस तरह दिखती है:

private static IEnumerable<IDataRecord> Retrieve(string sql, Action<SqlParameterCollection> addParameters)
{
    //ConnectionString is a private static property in the data layer
    // You can implement it to read from a config file or elsewhere
    using (var cn = new SqlConnection(ConnectionString))
    using (var cmd = new SqlCommand(sql, cn))
    {
        addParameters(cmd.Parameters);

        cn.Open();
        using (var rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
                yield return rdr;
            rdr.Close();
        }
    }
}

और यह मुझे सार्वजनिक डेटा स्तर विधियों को लिखने देता है जो पैरामीटर जोड़ने के लिए अनाम विधियों का उपयोग करते हैं। दिखाया गया कोड .Net 2.0+ के साथ काम करता है, लेकिन .Net 3.5 का उपयोग करके इसे और भी छोटा लिखा जा सकता है:

public IEnumerable<IDataRecord> GetFooChildrenByParentID(int ParentID)
{
    //I could easily use a stored procedure name instead of a full sql query
    return Retrieve(
        @"SELECT c.* 
         FROM [ParentTable] p 
         INNER JOIN [ChildTable] c ON c.ParentID = f.ID 
         WHERE f.ID= @ParentID", delegate(SqlParameterCollection p)
       {
          p.Add("@ParentID", SqlDbType.Int).Value = ParentID;
       }
     );
}

मैं यहीं रुकने वाला हूं ताकि मैं आपको फिर से उस कोड की ओर इंगित कर सकूं जो पैरामीटर निर्माण के लिए अनाम विधि का उपयोग करता है।

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

हालांकि, मैं यह बताना चाहता हूं कि यह सब एक साथ कैसे फिट बैठता है। बाकी काफी सीधा है, लेकिन इसे किसी सूची या समान में फेंकना और चीजों को गलत करना, अंततः प्रदर्शन को नुकसान पहुंचाना आसान है। इसलिए आगे बढ़ते हुए, व्यावसायिक परत क्वेरी परिणामों को ऑब्जेक्ट में अनुवाद करने के लिए फ़ैक्टरी का उपयोग करती है (c# 3.0 या बाद के संस्करण):

public class Foo
{
    //various normal properties and methods go here

    public static Foo FooFactory(IDataRecord record)
    {
        return new Foo
        {
            Property1 = record[0],
            Property2 = record[1]
            //...
        };
    }
}

इन्हें अपनी कक्षा में रखने के बजाय, आप उन सभी को एक स्थिर वर्ग में भी समूहित कर सकते हैं जो विशेष रूप से फ़ैक्टरी विधियों को धारण करने के लिए अभिप्रेत है।

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

private static IEnumerable<T> Retrieve(Func<IDataRecord, T> factory,
                  string sql, Action<SqlParameterCollection> addParameters)
{
    //ConnectionString is a private static property in the data layer
    // You can implement it to read from a config file or elsewhere
    using (var cn = new SqlConnection(ConnectionString))
    using (var cmd = new SqlCommand(sql, cn))
    {
        addParameters(cmd.Parameters);

        cn.Open();
        using (var rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
                yield return factory(rdr);
            rdr.Close();
        }
    }
}

और अब हम उस नई पुनर्प्राप्ति () विधि को इस तरह कहेंगे:

public IEnumerable<Foo> GetFooChildrenByParentID(int ParentID)
{
    //I could easily use a stored procedure name instead of a full sql query
    return Retrieve(Foo.FooFactory,
        @"SELECT c.* 
         FROM [ParentTable] p 
         INNER JOIN [ChildTable] c ON c.ParentID = f.ID 
         WHERE f.ID= @ParentID", delegate(SqlParameterCollection p)
       {
          p.Add("@ParentID", SqlDbType.Int).Value = ParentID;
       }
     );
}

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

अपडेट/बनाएं कोड समान है, इस अंतर के साथ कि आप आमतौर पर एक समय में केवल एक रिकॉर्ड बदल रहे हैं, न कि कई।

या, मैं आपको इस लंबी पोस्ट को पढ़ने से बचा सकता हूं और आपको केवल एंटिटी फ्रेमवर्क का उपयोग करने के लिए कह सकता हूं;)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या मेरे पास SQL ​​​​सर्वर में एक दृश्य में एक कॉलम का संदर्भ देने वाली एक विदेशी कुंजी हो सकती है?

  2. SQL सर्वर में लॉजिकल ऑपरेटर के बीच क्या है - SQL सर्वर / TSQL ट्यूटोरियल पार्ट 124

  3. .NET/SQL सर्वर में कनेक्शन पूलिंग?

  4. WHERE col IN (...) कंडीशन पर सीमा

  5. SQL सर्वर में टेस्ट डेटा कैसे जेनरेट करें