BULK INSERT स्टेटमेंट के प्रदर्शन की जांच कैसे की जाती है?


12

मैं मुख्य रूप से एंटिटी फ्रेमवर्क ORM का उपयोग कर एक .NET डेवलपर हूं। हालाँकि, क्योंकि मैं ORM का उपयोग करने में विफल नहीं होना चाहता , मैं यह समझने की कोशिश कर रहा हूं कि डेटा लेयर (डेटाबेस) के भीतर क्या होता है। मूल रूप से, विकास के दौरान मैं प्रोफाइलर शुरू करता हूं और जांचता हूं कि प्रश्नों के संदर्भ में कोड के कुछ हिस्से क्या उत्पन्न करते हैं।

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

यह डेटाबेस ज्ञान के मेरे स्तर के लिए ठीक काम करता है। हालाँकि, BULK INSERT एक विशेष प्राणी प्रतीत होता है , क्योंकि यह SHOWPLAN का उत्पादन नहीं करता है

मैं एक बहुत ही सरल उदाहरण प्रस्तुत करने का प्रयास करूंगा:

तालिका परिभाषा

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)

नोट: कोई अन्य सूचकांक तालिका पर परिभाषित नहीं हैं

बल्क इंसर्ट (जो मैं प्रोफाइलर में पकड़ता हूं, केवल एक बैच)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] Int, [ImportingSystemId] Int, [FileName] NVarChar(64) COLLATE Latin1_General_CI_AS, [FileImportTime] DateTime2(7))

मेट्रिक्स

  • 695 आइटम डाले गए
  • सीपीयू = 31
  • पढ़ता है = 4271
  • लिखता है = २४
  • अवधि = 154
  • कुल तालिका संख्या = 11500

मेरे आवेदन के लिए, यह ठीक है, हालांकि रीड्स बड़ा लगता है (मैं SQL सर्वर इंटर्नल के बारे में बहुत कम जानता हूं, इसलिए मैं 8K पृष्ठ के आकार और मेरे पास मौजूद छोटे रिकॉर्ड की तुलना करता हूं)

प्रश्न: अगर इस बल्क इंसर्ट को अनुकूलित किया जा सकता है तो मैं कैसे जांच कर सकता हूं? या इसका कोई मतलब नहीं है, क्योंकि यह यकीनन सबसे बड़ा डेटा क्लाइंट एप्लिकेशन से SQL सर्वर पर धकेलने का सबसे तेज़ तरीका है?

जवाबों:


14

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

1. क्लस्टरिंग ऑर्डर में डेटा डालें

SQL सर्वर अक्सर तालिका में एक क्लस्टर इंडेक्स के साथ डालने से पहले डेटा को सॉर्ट करेगा। कुछ तालिकाओं और अनुप्रयोगों के लिए आप फ्लैट फ़ाइल में डेटा को सॉर्ट करके प्रदर्शन को बेहतर बना सकते हैं और SQL सर्वर को बता सकते हैं कि डेटा को ORDERतर्क के माध्यम से क्रमबद्ध किया गया है BULK INSERT:

आदेश ({कॉलम [ASC | DESC]} [, ... n])

निर्दिष्ट करता है कि डेटा फ़ाइल में डेटा कैसे सॉर्ट किया गया है। यदि आयात किए जा रहे डेटा को टेबल पर क्लस्टर किए गए इंडेक्स के अनुसार क्रमबद्ध किया जाता है, तो थोक आयात प्रदर्शन में सुधार होता है।

चूँकि आप एक IDENTITYस्तंभ को संकुल कुंजी के रूप में उपयोग कर रहे हैं, इसलिए आपको इस बारे में चिंता करने की आवश्यकता नहीं है।

2. TABLOCKयदि संभव हो तो उपयोग करें

यदि आपको अपनी तालिका में केवल एक सत्र डेटा डालने की गारंटी दी जाती है, तो आप इसके लिए TABLOCKतर्क निर्दिष्ट कर सकते हैं BULK INSERT। यह लॉक विवाद को कम कर सकता है और कुछ परिदृश्यों में न्यूनतम लॉगिंग को जन्म दे सकता है। हालाँकि, आप एक तालिका में एक सम्मिलित सूचकांक के साथ सम्मिलित कर रहे हैं जिसमें पहले से ही डेटा शामिल है ताकि आपको ट्रेस ध्वज 610 के बिना न्यूनतम लॉगिंग न मिले जो बाद में इस उत्तर में उल्लिखित है।

यदि TABLOCKसंभव नहीं है, क्योंकि आप कोड नहीं बदल सकते हैं , तो सभी आशा खो नहीं है। उपयोग करने पर विचार करें sp_table_option:

EXEC [sys].[sp_tableoption]
    @TableNamePattern = N'dbo.BulkLoadTable' ,
    @OptionName = 'table lock on bulk load' , 
    @OptionValue = 'ON'

एक अन्य विकल्प ट्रेस फ्लैग 715 को सक्षम करना है ।

3. एक उपयुक्त बैच आकार का उपयोग करें

कभी-कभी आप बैच आकार को बदलकर आवेषण को ट्यून करने में सक्षम होंगे।

ROWS_PER_BATCH = row_per_batch

डेटा फ़ाइल में डेटा की पंक्तियों की अनुमानित संख्या को इंगित करता है।

डिफ़ॉल्ट रूप से, डेटा फ़ाइल का सारा डेटा सर्वर को एकल लेनदेन के रूप में भेजा जाता है, और बैच में पंक्तियों की संख्या क्वेरी ऑप्टिमाइज़र के लिए अज्ञात है। यदि आप ROWS_PER_BATCH (एक मान> 0 के साथ) निर्दिष्ट करते हैं, तो सर्वर इस मान का उपयोग बल्क-आयात ऑपरेशन को अनुकूलित करने के लिए करता है। ROWS_PER_BATCH के लिए निर्दिष्ट मान लगभग पंक्तियों की वास्तविक संख्या के समान होना चाहिए। प्रदर्शन के विचारों के बारे में जानकारी के लिए, इस विषय में बाद में "रिमार्क्स" देखें।

यहाँ लेख में बाद में बोली है:

यदि किसी एकल बैच में फ्लश किए जाने वाले पृष्ठों की संख्या एक आंतरिक सीमा से अधिक हो जाती है, तो बैच के शुरू होने पर कौन से पृष्ठों को फ्लश करना है, इसकी पहचान करने के लिए बफर पूल की एक पूरी स्कैन हो सकती है। यह पूर्ण स्कैन थोक-आयात प्रदर्शन को चोट पहुंचा सकता है। आंतरिक सीमा से अधिक होने का एक संभावित मामला तब होता है जब एक बड़े बफर पूल को धीमे I / O सबसिस्टम के साथ जोड़ा जाता है। बड़ी मशीनों पर बफर ओवरफ्लो से बचने के लिए, या तो टैब्लॉक हिंट (जो कि बल्क ऑप्टिमाइजेशन को हटा देगा) का उपयोग न करें या छोटे बैच साइज (जो बल्क ऑप्टिमाइजेशन को संरक्षित करता है) का उपयोग करें।

क्योंकि कंप्यूटर भिन्न होते हैं, हम अनुशंसा करते हैं कि आप अपने डेटा लोड के साथ विभिन्न बैच आकारों का परीक्षण करें ताकि यह पता लगाया जा सके कि आपके लिए सबसे अच्छा क्या है।

व्यक्तिगत रूप से मैं सिर्फ एक ही बैच में सभी 695 पंक्तियाँ सम्मिलित करूंगा। हालांकि बहुत सारे डेटा सम्मिलित करते समय बैच आकार को ट्यूनिंग करना एक बड़ा अंतर बना सकता है।

4. सुनिश्चित करें कि आपको IDENTITYकॉलम की आवश्यकता है

मुझे आपके डेटा मॉडल या आवश्यकताओं के बारे में कुछ भी पता नहीं है, लेकिन IDENTITYहर तालिका में एक कॉलम जोड़ने के जाल में मत पड़ो । हारून बर्ट्रेंड ने इस लेख के बारे में कहा है कि बुरी आदतों को किक करने के लिए: प्रत्येक तालिका पर एक पहचान पत्र कॉलम डालना । स्पष्ट होने के लिए, मैं यह नहीं कह रहा हूं कि आपको IDENTITYइस तालिका से कॉलम को हटा देना चाहिए । हालांकि, यदि आप यह निर्धारित करते हैं कि IDENTITYकॉलम आवश्यक नहीं है और इसे हटा दें जो सम्मिलित प्रदर्शन में सुधार कर सकता है।

5. अनुक्रमणिका या बाधाओं को अक्षम करें

यदि आपके पास पहले से मौजूद डेटा की तुलना में बड़ी मात्रा में डेटा तालिका में लोड हो रहा है, तो लोड से पहले अनुक्रमित या बाधाओं को अक्षम करने और लोड के बाद उन्हें सक्षम करने के लिए तेज़ हो सकता है। बड़ी मात्रा में डेटा के लिए यह आमतौर पर SQL सर्वर के लिए एक इंडेक्स बनाने के लिए अधिक अक्षम होता है, बजाय इसके कि डेटा टेबल में लोड हो। ऐसा लगता है कि आपने 11500 पंक्तियों के साथ एक तालिका में 695 पंक्तियां डालीं, इसलिए मैं इस तकनीक की सिफारिश नहीं करूंगा।

6. टीएफ 610 पर विचार करें

ट्रेस फ्लैग 610 कुछ अतिरिक्त परिदृश्यों में न्यूनतम लॉगिंग की अनुमति देता है। एक IDENTITYसंकुल कुंजी के साथ अपनी तालिका के लिए , आपको किसी भी नए डेटा पृष्ठों के लिए न्यूनतम लॉगिंग तब तक प्राप्त होगी जब तक कि आपका पुनर्प्राप्ति मॉडल सरल या बल्क-लॉग न हो। मेरा मानना ​​है कि यह सुविधा डिफ़ॉल्ट रूप से नहीं है क्योंकि यह कुछ प्रणालियों पर प्रदर्शन को नीचा दिखा सकता है। इस ट्रेस ध्वज को सक्षम करने से पहले आपको सावधानीपूर्वक परीक्षण करने की आवश्यकता होगी। अनुशंसित Microsoft संदर्भ अभी भी डेटा लोड हो रहा है प्रदर्शन मार्गदर्शिका प्रतीत होता है

आई / ओ मिनिमल लॉगिंग अंडर ट्रेस फ्लैग 610

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

यदि आपका लोड परिदृश्य छोटे पेड़ों पर डाला गया ऑपरेशन है जो चेकपॉइंट सीमाओं को पार नहीं करता है, और आपके पास धीमी आई / ओ प्रणाली है, तो न्यूनतम लॉगिंग का उपयोग वास्तव में सम्मिलित गति को धीमा कर सकता है।

जहां तक ​​मैं बता सकता हूं कि इसका पता लगाने वाले झंडे 610 के साथ कुछ भी नहीं है, बल्कि न्यूनतम लॉगिंग के साथ ही है। मेरा मानना ​​है कि ROWS_PER_BATCHट्यूनिंग के बारे में पहले वाला उद्धरण इसी अवधारणा पर हो रहा था।

अंत में, शायद इतना नहीं है कि आप अपनी धुन बना सकें BULK INSERT। मुझे आपके द्वारा सम्मिलित किए जाने के साथ पढ़ने वाली गणना के बारे में चिंता नहीं होगी। SQL सर्वर रिपोर्ट दर्ज करेगा जब भी आप डेटा डालेंगे। निम्नलिखित बहुत सरल पर विचार करें INSERT:

DROP TABLE IF EXISTS X_TABLE;

CREATE TABLE X_TABLE (
VAL VARCHAR(1000) NOT NULL
);

SET STATISTICS IO, TIME ON;

INSERT INTO X_TABLE WITH (TABLOCK)
SELECT REPLICATE('Z', 1000)
FROM dbo.GetNums(10000); -- generate 10000 rows

इससे आउटपुट SET STATISTICS IO, TIME ON:

तालिका 'X_TABLE'। स्कैन संख्या 0, तार्किक 11428 पढ़ता है

मेरे पास 11428 रिपोर्ट पढ़ी गई हैं, लेकिन यह कार्रवाई योग्य जानकारी नहीं है। कभी-कभी रिपोर्ट किए गए रीड्स की संख्या न्यूनतम लॉगिंग द्वारा कम की जा सकती है, लेकिन निश्चित रूप से अंतर को प्रदर्शन लाभ में सीधे अनुवाद नहीं किया जा सकता है।


12

मैं इस प्रश्न का उत्तर देना शुरू करने जा रहा हूं, इस उत्तर को लगातार अपडेट करने के इरादे से क्योंकि मैं ट्रिक्स का ज्ञान आधार बनाता हूं। उम्मीद है कि अन्य लोग इस पर आते हैं और मुझे इस प्रक्रिया में अपना ज्ञान सुधारने में मदद करते हैं।

  1. आंत की जाँच करें: क्या आपका फ़ायरवॉल स्टेटफुल, डीप पैकेट निरीक्षण कर रहा है? इस बारे में आपको इंटरनेट पर बहुत कुछ नहीं मिलेगा, लेकिन अगर आपके थोक आवेषण लगभग 10x धीमे हैं, तो वे क्या होने चाहिए, संभावना है कि आपके पास सुरक्षा उपकरण स्तर 3-7 के गहरे पैकेट निरीक्षण और "जेनेरिक एसक्यूएल इंजेक्शन रोकथाम" के लिए जाँच हो। "।

  2. उस डेटा का आकार मापें, जिसे आप बाइट्स में, प्रति बैच में डालने की योजना बनाते हैं। और जांचें कि क्या आप कोई एलओबी डेटा स्टोर कर रहे हैं, क्योंकि यह एक अलग पेज लाने और लिखने का ऑपरेशन है।

    कई कारणों से आपको इसे इस तरह करना चाहिए:

    ए। AWS में, इलास्टिक ब्लॉक स्टोरेज IOPS बाइट्स में टूट जाते हैं, न कि पंक्तियों में।

    1. लिनक्स उदाहरणों पर अमेज़ॅन ईबीएस वॉल्यूम प्रदर्शन देखें I / O विशेषताओं और निगरानी के लिए एक ईबीएस IOPS इकाई क्या है
    2. विशेष रूप से, जनरल पर्पस SSD (gp2) वॉल्यूम में "I / O क्रेडिट्स और बर्स्ट परफॉर्मेंस" कांसेप्ट है और भारी ईटीएल प्रोसेसिंग के लिए बर्स्ट बैलेंस क्रेडिट्स के लिए यह आम बात है। आपकी फट अवधि को बाइट्स में मापा जाता है, न कि SQL सर्वर पंक्तियों :)

    ख। जबकि अधिकांश लाइब्रेरी या व्हाइटपैपर्स पंक्तियों की संख्या के आधार पर परीक्षण करते हैं, यह वास्तव में उन पृष्ठों की संख्या है जो उस मामले को लिखा जा सकता है, और, यह गणना करने के लिए, आपको पता होना चाहिए कि प्रति पंक्ति कितने बाइट्स और आपके पृष्ठ का आकार (आमतौर पर 8KB) , लेकिन हमेशा दोहरा जांच करें कि क्या आपको सिस्टम किसी और से विरासत में मिला है।)

    SELECT *
    FROM 
    sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N'YourTable'), NULL, NULL, 'DETAILED')

    Avg_record_size_in_bytes और page_count पर ध्यान दें।

    सी। जैसा कि पॉल व्हाइट https://sqlperformance.com/2019/05/sql-performance/minimal-log-insert-select-heap में बताते हैं , "कम से कम लॉगिंग को सक्षम करने के लिए INSERT...SELECT, SQL सर्वर को कुल आकार के साथ 250 से अधिक पंक्तियों की अपेक्षा करनी चाहिए कम से कम एक सीमा (8 पृष्ठ)। "

  3. यदि आपके पास चेक बाधाओं, या अद्वितीय बाधाओं, उपयोग SET STATISTICS IO ONऔर SET STATISTICS TIME ON(या SQL सर्वर प्रोफाइलर या SQL सर्वर विस्तारित ईवेंट) के साथ कोई भी अनुक्रमणिका है, तो सूचना को कैप्चर करने के लिए जैसे कि आपके बल्क इंसर्ट का कोई रीड ऑपरेशंस है या नहीं। पढ़ें कार्रवाई SQL सर्वर डेटाबेस इंजन अखंडता बाधाओं पास सुनिश्चित करने के कारण कर रहे हैं।

  4. एक परीक्षण डेटाबेस बनाने की कोशिश करें जहां RAM ड्राइव पर PRIMARYFILEGROUP माउंट किया गया है। यह SSD की तुलना में थोड़ा तेज़ होना चाहिए, लेकिन साथ ही किसी भी प्रश्न को समाप्त करना चाहिए कि क्या आपका RAID नियंत्रक ओवरहेड जोड़ सकता है। 2018 में, यह नहीं होना चाहिए, लेकिन इस तरह की कई अंतर आधार रेखाएं बनाकर, आप एक सामान्य विचार प्राप्त कर सकते हैं कि आपका हार्डवेयर कितना ओवरहेड जोड़ रहा है।

  5. साथ ही सोर्स फाइल को रैम ड्राइव पर रखें।

    यदि आप अपने डेटाबेस सर्वर के FILEGROUP पर उसी ड्राइव से स्रोत फ़ाइल पढ़ रहे हैं, तो रैम फ़ाइल पर स्रोत फ़ाइल को रखना किसी भी विवाद के मुद्दों को दूर करेगा।

  6. सत्यापित करें कि आपने 64KB extents का उपयोग करके अपनी हार्ड ड्राइव को स्वरूपित किया है।

  7. UserBenchmark.com का उपयोग करें और अपने SSD को बेंचमार्क करें। यह करेगा:

    1. डिवाइस से क्या प्रदर्शन करना है, इसके बारे में अन्य प्रदर्शन aficionados को अधिक ज्ञान जोड़ें
    2. यदि आपकी ड्राइव का प्रदर्शन उसी सटीक ड्राइव के साथ अंडर पर्मिंग कर रहा है, तो यह पता लगाने में आपकी सहायता करें
    3. यदि आपकी ड्राइव का प्रदर्शन उसी श्रेणी (SSD, HDD, इत्यादि) में अन्य ड्राइव को अंडर-परफॉर्म करता है, तो यह पता लगाने में आपकी मदद करें।
  8. यदि आप इकाई फ्रेमवर्क एक्सटेंशन के माध्यम से C # से "INSERT BULK" कॉल कर रहे हैं, तो सुनिश्चित करें कि आपने पहले JIT को "वार्म अप" किया और पहले कुछ परिणाम "फेंक" दिए।

  9. अपने प्रोग्राम के लिए प्रदर्शन काउंटर बनाने का प्रयास करें। .NET के साथ, आप बेंचमार्क .NET का उपयोग कर सकते हैं और यह स्वचालित रूप से बुनियादी मैट्रिक्स का एक गुच्छा प्रोफाइल करेगा। फिर आप खुले स्रोत समुदाय के साथ अपने प्रोफाइलर के प्रयासों को साझा कर सकते हैं, और यह देख सकते हैं कि विभिन्न हार्डवेयर चलाने वाले लोग एक ही मैट्रिक्स की रिपोर्ट करते हैं (जैसे कि मेरे पहले बिंदु से UserBenchmark.com का उपयोग करने के लिए तुलना करने के बारे में)।

  10. नामित पाइप का उपयोग करने की कोशिश करें और इसे लोकलहोस्ट के रूप में चलाएं।

  11. यदि आप SQL सर्वर को लक्षित कर रहे हैं और .NET कोर का उपयोग कर रहे हैं, तो SQL सर्वर Std संस्करण के साथ लिनक्स को स्पिन करने पर विचार करें - यह गंभीर हार्डवेयर के लिए प्रति घंटे एक डॉलर से भी कम खर्च होता है। एक ही हार्डवेयर के साथ एक ही कोड को एक अलग ओएस के साथ आज़माने का बड़ा फायदा यह देखने के लिए है कि क्या OS कर्नेल के TCP / IP स्टैक में समस्या आ रही है।

  12. अपने डेटाबेस तालिका के FILEGROUP को संग्रहीत करने के लिए ड्राइव विलंबता को मापने के लिए ग्लेन बैरी की SQL सर्वर डायग्नोस्टिक क्वेरी का उपयोग करें।

    ए। अपने परीक्षण से पहले और अपने परीक्षण के बाद माप करना सुनिश्चित करें। "आपके परीक्षण से पहले" आपको बताता है कि क्या आपको आधारभूत के रूप में भयानक IO विशेषताएँ मिली हैं।

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

    क्यों? क्योंकि अधिकांश डेटाबेस सर्वर कुछ प्रकार के नेटवर्क संलग्न भंडारण (एनएएस) का उपयोग करते हैं। क्लाउड में, AWS में, इलास्टिक ब्लॉक स्टोरेज बस यही है। आप अपने ईबीएस वॉल्यूम / एनएएस समाधान के आईओपीएस से बाध्य हो सकते हैं।

  13. प्रतीक्षा आंकड़ों को मापने के लिए कुछ टूल का उपयोग करें। लाल गेट SQL मॉनिटर , SolarWinds डेटाबेस प्रदर्शन विश्लेषक, या यहां तक ​​कि ग्लेन बैरी की SQL सर्वर डायग्नोस्टिक क्वेरी, या पॉल रैंडल की प्रतीक्षा सांख्यिकी क्वेरी

    ए। सबसे आम इंतजार प्रकार की संभावना मेमोरी / सीपीयू, WRITELOG, PAGEIOLATCH_EX, और हो जाएगा ASYNC_NETWORK_IO

    ख। यदि आप उपलब्धता समूह चला रहे हैं तो आप अतिरिक्त प्रतीक्षा प्रकारों को अपना सकते हैं।

  14. अक्षम के INSERT BULKसाथ कई, एक साथ आदेशों के प्रभाव को मापें TABLOCK(TABLOCK INSERT BULK कमांडों के क्रमबद्धता को बल देगा)। आपकी अड़चन INSERT BULKपूरी होने की प्रतीक्षा कर सकती है ; आपको अपने डेटाबेस सर्वर के भौतिक डेटा मॉडल को संभालने के रूप में इनमें से कई कार्यों को कतारबद्ध करने का प्रयास करना चाहिए।

  15. अपनी तालिका को विभाजित करने पर विचार करें। एक विशेष उदाहरण के रूप में: यदि आपकी डेटाबेस तालिका केवल-मात्र है, तो एंड्रयू नोविक ने "TODAY" बनाने FILEGROUPऔर कम से कम दो फ़ाइल समूह, TODAY और BEFORE_TODAY में विभाजन करने का सुझाव दिया । इस तरह, यदि आपका INSERT BULKडेटा केवल आज के लिए डेटा है, तो आप एक एकल हिट करने के लिए सभी आवेषणों को मजबूर करने के लिए एक CreatedOn फ़ील्ड पर फ़िल्टर कर सकते हैं FILEGROUP, और इस तरह उपयोग करते समय अवरुद्ध को कम कर सकते हैं TABLOCK। Microsoft Whitepaper: Partitioned Table और Index Strategies में SQL Server 2008 का उपयोग करके इस तकनीक को और अधिक विस्तार से वर्णित किया गया है

  16. यदि आप कॉलमस्टोर इंडेक्स का उपयोग कर रहे हैं, तो TABLOCK102,400 पंक्तियों बैच आकार में डेटा को बंद और लोड करें। फिर आप अपने सभी डेटा को सीधे कॉलमस्टोरोर रांगग्रुप में समानांतर में लोड कर सकते हैं। यह सुझाव (और प्रलेखित तर्कसंगत) Microsoft के Columnstore अनुक्रमित से आता है - डेटा लोडिंग मार्गदर्शन :

    बल्क लोडिंग में इन अंतर्निहित प्रदर्शन अनुकूलन हैं:

    समानांतर भार: आपके पास कई समवर्ती थोक भार (bcp या बल्क इंसर्ट) हो सकते हैं जो प्रत्येक एक अलग डेटा फ़ाइल को लोड कर रहे हैं। SQL सर्वर में rowstore बल्क लोड के विपरीत, आपको यह निर्दिष्ट करने की आवश्यकता नहीं है TABLOCKक्योंकि प्रत्येक बल्क आयात धागा उस पर अनन्य लॉक के साथ एक अलग rowgroups (संपीड़ित या डेल्टा rowgroups) में डेटा को विशेष रूप से लोड करेगा। उपयोग TABLOCKकरने से मेज पर एक विशेष ताला लग जाएगा और आप समानांतर में डेटा आयात नहीं कर पाएंगे।

    न्यूनतम लॉगिंग:एक बल्क लोड डेटा पर न्यूनतम लॉगिंग का उपयोग करता है जो सीधे पंक्तिबद्ध समूहों को जाता है। कोई भी डेटा जो डेल्टा रोटरग्रुप में जाता है, पूरी तरह से लॉग इन होता है। इसमें किसी भी बैच का आकार शामिल है जो 102,400 पंक्तियों से कम है। हालांकि, बल्क लोडिंग के साथ लक्ष्य अधिकांश डेटा के लिए डेल्टा रोटरग्रुप को बायपास करना है।

    लॉकिंग ऑप्टिमाइज़ेशन: जब कंप्रेस्ड रोगग्रुप में लोड किया जाता है, तो रॉगग्रुप पर एक्स लॉक का अधिग्रहण किया जाता है। हालाँकि, जब डेल्टा रोटरग्रुप में बल्क लोडिंग होती है, तो एक रिंग लॉक को रिगग्रुप में अधिग्रहीत कर लिया जाता है, लेकिन एसक्यूएल सर्वर अभी भी ताले को लॉक करता है।

  17. SQL सर्वर 2016 के अनुसार, अब अनुक्रमित तालिका में न्यूनतम लॉगिंग के लिए ट्रेस ध्वज 610 को सक्षम करने की आवश्यकता नहीं है । Microsoft इंजीनियर परीक्षित सवानी ( जोर मेरा ) का उद्धरण :

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

    SQL Server 2016 में इन एन्हांसमेंट के भाग के रूप में, आपको अब अनुक्रमित तालिका में न्यूनतम लॉगिंग के लिए ट्रेस ध्वज 610 को सक्षम करने की आवश्यकता नहीं हैऔर यह इतिहास का हिस्सा बनने के लिए कुछ अन्य ट्रेस झंडे (1118, 1117, 1236, 8048) से जुड़ता है। SQL सर्वर 2016 में, जब बल्क लोड ऑपरेशन के कारण एक नया पृष्ठ आवंटित किया जाता है, तो सभी पंक्तियों को क्रमिक रूप से भरने के लिए उस नए पृष्ठ को न्यूनतम रूप से लॉग किया जाता है, यदि पहले चर्चा की गई न्यूनतम लॉगिंग के लिए अन्य सभी पूर्व आवश्यकताएं पूरी होती हैं। अनुक्रमणिका क्रम को बनाए रखने के लिए मौजूदा पृष्ठों (कोई नया पृष्ठ आवंटन) में डाली गई पंक्तियाँ अभी भी पूरी तरह से लॉग नहीं हैं, क्योंकि वे पंक्तियाँ हैं जो लोड के दौरान पृष्ठ विभाजन के परिणामस्वरूप स्थानांतरित हो जाती हैं। यह भी महत्वपूर्ण है कि ALLOW_PAGE_LOCKS चालू होने के लिए कम से कम लॉगिंग ऑपरेशन के लिए अनुक्रमणिका (जो कि डिफ़ॉल्ट रूप से चालू है) के लिए काम करें क्योंकि आवंटन के दौरान पृष्ठ लॉक प्राप्त होते हैं और इस प्रकार केवल पृष्ठ या सीमा आवंटन लॉग होते हैं।

  18. यदि आप C # या EntityFramework.Extensions (जिसमें हुड के तहत SqlBulkCopy का उपयोग करता है) में SqlBulkCopy का उपयोग कर रहे हैं, तो अपने बिल्ड कॉन्फ़िगरेशन की जांच करें। क्या आप रिलीज़ मोड में अपने परीक्षण चला रहे हैं? क्या लक्ष्य आर्किटेक्चर किसी भी सीपीयू / x64 / x86 पर सेट है?

  19. यह देखने के लिए sp_who2 का उपयोग करें कि क्या INSERT BULK लेनदेन SUSPENDED है या नहीं। इसे SUSPENDED किया जा सकता है क्योंकि यह किसी अन्य स्पिड द्वारा अवरुद्ध है। SQL सर्वर ब्लॉकिंग को कम करने के तरीके को पढ़ने पर विचार करें । आप एडम मचानिक के sp_WhoIsActive का भी उपयोग कर सकते हैं, लेकिन sp_who2 आपको बुनियादी जानकारी की आवश्यकता देगा।

  20. आपके पास बस खराब डिस्क I / O हो सकती है। यदि आपका बल्क इंसर्ट कर रहा है और आपकी डिस्क का उपयोग 100% नहीं हो रहा है, और लगभग 2% पर अटका हुआ है, तो संभवतः आपके पास खराब फर्मवेयर, या दोषपूर्ण I / O डिवाइस है। (यह मेरी एक सहकर्मी के लिए हुआ।) हार्डवेयर प्रदर्शन के लिए दूसरों के साथ तुलना करने के लिए [SSD UserBenchmark] का उपयोग करें, खासकर यदि आप अपने स्थानीय देव मशीन पर सुस्ती को दोहरा सकते हैं। (मैंने इसे अंतिम सूची में रखा है क्योंकि ज्यादातर कंपनियां आईपी जोखिम के कारण डेवलपर्स को अपने स्थानीय मशीन पर डेटाबेस चलाने की अनुमति नहीं देती हैं।)

  21. यदि आपकी तालिका संपीड़न का उपयोग करती है, तो आप कई सत्रों को चलाने का प्रयास कर सकते हैं, और प्रत्येक सत्र में, मौजूदा लेनदेन का उपयोग करके शुरू कर सकते हैं और SqlBulkCopy कमांड से पहले इसे चला सकते हैं:

    पूर्व गंभीर रूपांतरण प्रक्रिया निर्धारित क्षमता सीपीयू = ऑटो;

  22. सतत लोडिंग के लिए, विचारों की एक धारा, जिसे पहले Microsoft व्हाइटपेपर में विभाजित किया गया था , विभाजन तालिका और इंडेक्स स्ट्रेटेजी का उपयोग करते हुए डेटा सर्वर :

    निरंतर लोड हो रहा है

    OLTP परिदृश्य में, नया डेटा लगातार आ सकता है। यदि उपयोगकर्ता नवीनतम विभाजन को भी क्वेरी कर रहे हैं, तो लगातार डेटा डालने से अवरोध उत्पन्न हो सकता है: उपयोगकर्ता क्वेरी आवेषण को ब्लॉक कर सकते हैं, और इसी तरह, आवेषण उपयोगकर्ता प्रश्नों को ब्लॉक कर सकते हैं।

    लोडिंग टेबल या विभाजन पर ध्यान देना स्नैपशॉट अलगाव का उपयोग करके कम किया जा सकता है - विशेष रूप से, READ COMMITTED SNAPSHOTअलगाव स्तर। READ COMMITTED SNAPSHOTअलगाव के तहत , एक तालिका में आवेषण tempdb संस्करण स्टोर में गतिविधि का कारण नहीं बनता है , इसलिए आवेषण के लिए tempdb ओवरहेड न्यूनतम है, लेकिन समान विभाजन पर उपयोगकर्ता प्रश्नों द्वारा कोई साझा लॉक नहीं लिया जाएगा।

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

  23. Microsoft CAT टीम का डेटा लोड हो रहा है प्रदर्शन गाइड

  24. सुनिश्चित करें कि आपके आँकड़े अद्यतित हैं। यदि आप प्रत्येक अनुक्रमणिका के निर्माण के बाद FULLSCAN का उपयोग कर सकते हैं।

  25. SQL SQL के साथ SAN प्रदर्शन ट्यूनिंग और यह भी सुनिश्चित करें कि यदि आप मैकेनिकल डिस्क का उपयोग कर रहे हैं जो आपके डिस्क विभाजन संरेखित हैं। Microsoft का डिस्क विभाजन संरेखण सर्वोत्तम अभ्यास देखें

  26. COLUMNSTORE INSERT/ UPDATEप्रदर्शन


2

सम्मिलित होने के दौरान पढ़े जाने वाले अद्वितीय और FK अवरोध होने की संभावना है - यदि आप सम्मिलित करने के दौरान उन्हें अक्षम / ड्रॉप कर सकते हैं और बाद में उन्हें पुनः सक्षम कर सकते हैं तो आपको गति में सुधार हो सकता है। यदि आपको इसे सक्रिय रखने की तुलना में यह धीमा पड़ता है तो आपको परीक्षण करने की आवश्यकता होगी। यह भी एक अच्छा विचार नहीं हो सकता है यदि अन्य प्रक्रियाएं समान तालिका में लिख रही हैं। - गारेथ लियोन्स

क्यू एंड ए विदेशी कुंजी के अनुसार थोक डालने के बाद अविश्वास हो जाता है , एफके बाधाएं BULK INSERTबिना CHECK_CONSTRAINTSविकल्प के साथ अविश्वास हो जाती हैं (मेरा मामला जैसा कि मैं अविश्वास की बाधाओं के साथ समाप्त हो गया)। यह स्पष्ट नहीं है, लेकिन उन्हें जांचने और फिर भी अविश्वास करने का कोई मतलब नहीं होगा। हालांकि, PK और UNIQUE को अभी भी चेक किया जाएगा ( BULK INSERT (Transact-SQL) देखें )। - अलेक्सी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.