यदि टीवीपी अन्य विकल्पों की तुलना में "काफी धीमी" हैं, तो सबसे अधिक संभावना है कि आप उन्हें सही तरीके से लागू नहीं कर रहे हैं।
- आपको डेटाटेबल का उपयोग नहीं करना चाहिए, जब तक कि आपके एप्लिकेशन ने टीवीपी को मान भेजने के अलावा इसके लिए उपयोग नहीं किया है।
IEnumerable<SqlDataRecord>
. का उपयोग करना इंटरफ़ेस तेज़ है और कम मेमोरी का उपयोग करता है क्योंकि आप केवल डीबी को भेजने के लिए मेमोरी में संग्रह को डुप्लिकेट नहीं कर रहे हैं। मैंने इसे निम्नलिखित स्थानों पर प्रलेखित किया है:- मैं कम से कम समय में 10 मिलियन रिकॉर्ड कैसे सम्मिलित कर सकता हूं? (यहां बहुत सारी अतिरिक्त जानकारी और लिंक भी हैं)
- डिक्शनरी टू स्टोरेड प्रोसीजर टी-एसक्यूएल
- स्ट्रीमिंग डेटा SQL सर्वर 2008 में किसी अनुप्रयोग से (SQLServerCentral.com पर; नि:शुल्क पंजीकरण आवश्यक)
-
आपको
AddWithValue
. का उपयोग नहीं करना चाहिए SqlParameter के लिए, हालांकि यह एक प्रदर्शन समस्या होने की संभावना नहीं है। लेकिन फिर भी, यह होना चाहिए:SqlParameter tvp = com.Parameters.Add("data", SqlDbType.Structured); tvp.Value = MethodThatReturnsIEnumerable<SqlDataRecord>(MyCollection);
- टीवीपी टेबल वेरिएबल हैं और इसलिए आंकड़ों को बनाए नहीं रखते हैं। मतलब, वे क्वेरी ऑप्टिमाइज़र को केवल 1 पंक्ति होने की रिपोर्ट करते हैं। तो, आपकी खरीद में, या तो:
- एक साधारण चयन के अलावा किसी अन्य चीज़ के लिए TVP का उपयोग करके किसी भी प्रश्न पर स्टेटमेंट-लेवल रीकंपाइल का उपयोग करें:
OPTION (RECOMPILE)
- स्थानीय अस्थायी तालिका बनाएं (अर्थात एकल
#
) और टीवीपी की सामग्री को अस्थायी तालिका में कॉपी करें - आप उपयोगकर्ता-निर्धारित तालिका प्रकार में संकुल प्राथमिक कुंजी जोड़ने का प्रयास कर सकते हैं
- यदि SQL सर्वर 2014 या नए का उपयोग कर रहे हैं, तो आप इन-मेमोरी OLTP / मेमोरी-अनुकूलित तालिकाओं का उपयोग करने का प्रयास कर सकते हैं। कृपया देखें:मेमोरी ऑप्टिमाइज़ेशन का उपयोग करके तेज़ अस्थायी तालिका और तालिका चर
- एक साधारण चयन के अलावा किसी अन्य चीज़ के लिए TVP का उपयोग करके किसी भी प्रश्न पर स्टेटमेंट-लेवल रीकंपाइल का उपयोग करें:
आप क्यों देख रहे हैं इसके बारे में:
insert into @data ( ... fields ... ) values ( ... values ... )
-- for each row
insert into @data ( ... fields ... ) values ( ... values ... )
इसके बजाय:
insert into @data ( ... fields ... )
values ( ... values ... ),
( ... values ... ),
अगर वास्तव में ऐसा हो रहा है, तो:
- यदि लेन-देन के भीतर सम्मिलन किया जा रहा है तो कोई वास्तविक प्रदर्शन अंतर नहीं है
- नई वैल्यू-लिस्ट सिंटैक्स (यानी
VALUES (row1), (row2), (row3)
) 1000 पंक्तियों जैसी किसी चीज़ तक सीमित है और इसलिए उन टीवीपी के लिए व्यवहार्य विकल्प नहीं है जिनके पास वह सीमा नहीं है। हालांकि, यह संभावना नहीं है कि अलग-अलग आवेषण का उपयोग किया जा रहा है, यह देखते हुए किINSERT INTO @data (fields) SELECT tab.[col] FROM (VALUES (), (), ...) tab([col])
, जिसे मैंने यहां प्रलेखित किया है:टेबल वैल्यू कंस्ट्रक्टर के लिए पंक्तियों की अधिकतम संख्या . इसके बजाय... - इसका कारण सबसे अधिक संभावना है कि अलग-अलग सम्मिलन करने से ऐप कोड से मानों को SQL सर्वर में स्ट्रीम करने की अनुमति मिलती है:
- एक पुनरावर्तक का उपयोग करना (यानी
IEnumerable<SqlDataRecord>
उपरोक्त # 1 में नोट किया गया), ऐप कोड प्रत्येक पंक्ति को भेजता है क्योंकि यह विधि से लौटाया जाता है, और VALUES (), (), ...
का निर्माण करना सूची, भले हीINSERT INTO ... SELECT FROM (VALUES ...)
दृष्टिकोण (जो 1000 पंक्तियों तक सीमित नहीं है), जिसके लिए अभी भी संपूर्ण . के निर्माण की आवश्यकता होगीVALUES
कोई भी भेजने से पहले सूची SQL सर्वर में डेटा का। यदि बहुत अधिक डेटा है, तो सुपर-लॉन्ग स्ट्रिंग के निर्माण में अधिक समय लगेगा, और इसे करते समय यह बहुत अधिक मेमोरी लेगा।
- एक पुनरावर्तक का उपयोग करना (यानी
कृपया SQL सर्वर ग्राहक सलाहकार टीम का यह श्वेतपत्र भी देखें:TVP के साथ थ्रूपुट को अधिकतम करना