2010-01-26 18 views
8

में बड़ी मात्रा में डेटा हटाएं मान लीजिए कि मेरे पास 10000000 रिकॉर्ड वाला टेबल है। इन दो समाधानों के बीच क्या अंतर है?एसक्यूएल सर्वर

DELETE FROM MyTable 
  • पंक्ति द्वारा एक आवेदन पंक्ति के साथ डेटा को हटा:

    1. तरह नष्ट डेटा

      DELETE FROM MyTable WHERE ID = @SelectedID 
      

    पहला समाधान सबसे अच्छा प्रदर्शन है है? लॉग और प्रदर्शन पर असर क्या है?

  • उत्तर

    14

    यदि आपके पास अपनी तालिका में बहुत से रिकॉर्ड हैं और आप उन्हें सभी को हटाना चाहते हैं, तो आपको delete from <table> के बजाय truncate <table> पर विचार करना चाहिए। यह बहुत तेज़ होगा, लेकिन ध्यान रखें कि यह एक ट्रिगर को सक्रिय नहीं कर सकता है। , http://msdn.microsoft.com/en-us/library/aa260621%28SQL.80%29.aspx

    पंक्ति द्वारा आवेदन पंक्ति के भीतर तालिका हटाई जा रही लंबे लंबे समय में खत्म हो जाएगा, अपने डीबीएमएस कुछ भी अनुकूलित नहीं कर सकते के रूप में के रूप में:

    अधिक जानकारी के (इस मामले एसक्यूएल सर्वर 2000) के लिए देखें यह पहले से नहीं जानता है कि आप सबकुछ हटाने जा रहे हैं।

    +4

    यदि आप अभी भी लेनदेन के दायरे में हैं, तो आप एक ट्रंकेट रोलबैक कर सकते हैं, लोकप्रिय धारणा के विपरीत यह लेनदेनकृत है - अस्वीकृत आईएएम है प्रतिबद्ध होने तक हटाया नहीं गया है, इसलिए इसे आईएएम को बहाल करके वापस घुमाया जा सकता है। – Andrew

    +0

    बस इसे पढ़ें, और आप सही हैं, एसक्यूएल सर्वर में आप एक छंटनी रोलबैक कर सकते हैं। मेरे मन में ओरेकल था जहां यह संभव नहीं है (दस्तावेज़ीकरण के अनुसार)। –

    +0

    मैं TRUNCATE का उपयोग नहीं कर सकता क्योंकि मायटेबल में विदेशी कुंजी भी है, मुझे फिल्टर डेटा के लिए WHERE क्लॉज की आवश्यकता है –

    3

    पहले स्पष्ट रूप से बेहतर प्रदर्शन है।

    जब आप DELETE [MyTable] निर्दिष्ट करते हैं तो यह आईडी के लिए चेक किए बिना सबकुछ मिटा देगा। दूसरा इसे हटाने से पहले प्रत्येक बार एक संबंधित रिकॉर्ड का पता लगाने के लिए समय और डिस्क ऑपरेशन बर्बाद कर देगा।

    यह भी बदतर हो जाता है क्योंकि हर बार जब रिकॉर्ड तालिका के बीच से गायब हो जाता है, तो इंजन डिस्क पर डेटा को जोड़ना चाहता है, इस प्रकार समय बर्बाद कर सकता है और फिर से काम कर सकता है।

    शायद बेहतर विचार अवरुद्ध क्रम में क्लस्टर किए गए इंडेक्स कॉलम के आधार पर डेटा को हटाना होगा। फिर तालिका को मूल रूप से प्रत्येक डिलीट ऑपरेशन पर अंत से छोटा कर दिया जाएगा।

    +0

    कृपया मुझे बताओ क्यों। –

    +0

    आप कहते हैं कि: "शायद एक बेहतर विचार अवरुद्ध क्रम में क्लस्टर किए गए इंडेक्स कॉलम के आधार पर डेटा को हटाना होगा। फिर तालिका को मूल रूप से प्रत्येक डिलीट ऑपरेशन पर अंत से छोटा कर दिया जाएगा।" क्या आप और अधिक वर्णन कर सकते हैं? –

    +0

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

    3

    विकल्प 1 एक बहुत बड़ा लेनदेन तैयार करेगा और लॉग/प्रदर्शन पर एक बड़ा प्रभाव डालेगा, साथ ही साथ ताले बढ़ाना होगा ताकि तालिका अनुपलब्ध हो। विकल्प 2 धीमा हो जाएगा, हालांकि यह लॉग पर कम प्रभाव उत्पन्न करेगा (थोक/पूर्ण मोड मानते हैं)

    यदि आप सभी डेटा से छुटकारा पाना चाहते हैं, तो Truncate Table MyTable दोनों की तुलना में तेज़ होगा, हालांकि इसमें पंक्तियों को फ़िल्टर करने की कोई सुविधा नहीं है, यह पीछे की ओर मेटा डेटा परिवर्तन करता है और मूल रूप से तालिका में आईएएम को फर्श पर छोड़ देता है।

    +0

    मैं TRUNCATE का उपयोग नहीं कर सकता क्योंकि माईटेबल में विदेशी कुंजी भी है, मुझे फिल्टर डेटा के लिए WHERE क्लॉज की आवश्यकता है –

    0

    पहले मेज से सभी डेटा को हटा देंगे और बेहतर प्रदर्शन है कि अपने दूसरे जो एक विशिष्ट कुंजी से केवल डेटा को हटा देंगे होगा।

    अब अगर आप मेज से सभी डेटा हटाना है और आप उपयोग की रोलबैक थिंक का उपयोग कर पर भरोसा नहीं करते एक truncate table

    21

    आप क्या पंक्तियों को हटाना और ऐसा नहीं करने की आवश्यकता को प्रतिबंधित करने के लिए की जरूरत है

    DECLARE @RowsDeleted INTEGER 
    SET @RowsDeleted = 1 
    
    WHILE (@RowsDeleted > 0) 
        BEGIN 
         -- delete 10,000 rows a time 
         DELETE TOP (10000) FROM MyTable [WHERE .....] -- WHERE is optional 
         SET @RowsDeleted = @@ROWCOUNT 
        END 
    

    आम तौर पर, TRUNCATE: एक पूरी हटाने, या आप कम तालिका उपयोग नहीं कर सकते (जैसे तालिका एक FK बाधा द्वारा संदर्भित, या एक अनुक्रमित दृश्य में शामिल), तो आप मात्रा में हटाने के लिए कर सकते हैं सबसे अच्छा तरीका है और यदि संभव हो तो मैं इसका उपयोग करूंगा। लेकिन यह सभी परिदृश्यों में इस्तेमाल नहीं किया जा सकता है। साथ ही, ध्यान दें कि यदि कोई है तो TRUNCATE तालिका के लिए पहचान मान रीसेट करेगा।

    यदि आप SQL 2000 या इससे पहले का उपयोग कर रहे हैं, तो शीर्ष स्थिति उपलब्ध नहीं है, इसलिए आप इसके बजाय SET ROWCOUNT का उपयोग कर सकते हैं।

    DECLARE @RowsDeleted INTEGER 
    SET @RowsDeleted = 1 
    SET ROWCOUNT 10000 -- delete 10,000 rows a time 
    
    WHILE (@RowsDeleted > 0) 
        BEGIN 
         DELETE FROM MyTable [WHERE .....] -- WHERE is optional 
         SET @RowsDeleted = @@ROWCOUNT 
        END 
    
    +2

    आप SELECT/INSERT/UPDATE/DELETE TOP (N) के पक्ष में SET ROWCOUNT का उपयोग करने से दूर रहना चाहते हैं ... कारण? यहां एक नज़र डालें: http://msdn.microsoft.com/en-us/library/ms143729.aspx और यहां: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=282528 –

    +0

    अच्छा बिंदु (एसक्यूएल 2005 या बाद में मानना) जो शायद एक सुरक्षित शर्त है। मेरा जवाब अपडेट किया गया – AdaTheDev

    0

    यह post on Microsoft TechNet मिला।

    असल में, यह सिफारिश की गई है:

    1. चयन जांच का उपयोग कर जो डेटा आपको एक मध्यवर्ती मेज पर रखना चाहते हैं कॉपी करके;
    2. स्रोत तालिका को छोटा करें;
    3. इंटरमीडिएट तालिका से, स्रोत तालिका में डेटा से INSERT के साथ वापस कॉपी करें;

    ..

    BEGIN TRANSACTION 
    
    SELECT * 
        INTO dbo.bigtable_intermediate 
        FROM dbo.bigtable 
        WHERE Id % 2 = 0; 
    
        TRUNCATE TABLE dbo.bigtable; 
    
        SET IDENTITY_INSERT dbo.bigTable ON; 
        INSERT INTO dbo.bigtable WITH (TABLOCK) (Id, c1, c2, c3) 
        SELECT Id, c1, c2, c3 FROM dbo.bigtable_intermediate ORDER BY Id; 
        SET IDENTITY_INSERT dbo.bigtable OFF; 
    ROLLBACK TRANSACTION 
    
    संबंधित मुद्दे