কোনও শৃঙ্খলা ছাড়াই <টেবিল> থেকে বিশাল মোছার পদ্ধতিগুলি DE


37

এসকিউএল সার্ভার 2005 ব্যবহার করে।

আমি যেখানে ক্লজ নেই সেখানে একটি বিশাল মোছার কাজটি সম্পাদন করছি। এটি মূলত একটি ট্র্যাঙ্কেল টেবিল বিবরণের সমতুল্য - বাদে আমাকে ট্র্যাঙ্কেট ব্যবহার করার অনুমতি নেই। সমস্যাটি হ'ল টেবিলটি বিশাল - 10 মিলিয়ন সারি, এবং এটি সম্পূর্ণ হতে এক ঘন্টা সময় নেয়। এটি ছাড়া দ্রুত তৈরি করার কোনও উপায় আছে:

  • ছাঁটাই ব্যবহার করা হচ্ছে
  • সূচকগুলি অক্ষম বা বাদ দেওয়া হচ্ছে?

টি-লগ ইতিমধ্যে একটি পৃথক ডিস্কে রয়েছে।

কোন পরামর্শ স্বাগত!


2
যদি আপনি এটি অনেক কিছু করছেন, সারণীটি বিভাজন বিবেচনা করুন
গাইউস

1
টেবিলের রেফারেন্সে এফকে সীমাবদ্ধতার কারণে আপনি ট্রানসেট ব্যবহার করতে পারবেন না?
নিক চাম্মাস

উত্তর:


39

আপনি যা করতে পারেন তা হ'ল ব্যাচ মুছে ফেলা:

SELECT 'Starting' --sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
    DELETE TOP (xxx) MyTable

যেখানে এক্সএক্সএক্স, 50000 বলুন

এর একটি পরিবর্তন, আপনি যদি সারিগুলির একটি খুব উচ্চ শতাংশ মুছে ফেলতে চান ...

SELECT col1, col2, ... INTO #Holdingtable
           FROM MyTable WHERE ..some condition..

SELECT 'Starting' --sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
    DELETE TOP (xxx) MyTable WHERE ...

INSERT MyTable (col1, col2, ...)
           SELECT col1, col2, ... FROM #Holdingtable

3
@ টিস্যু: প্রতিটি মুছে ফেলার ক্ষেত্রে ত্রুটির ক্ষেত্রে কিছুটা লগ স্পেস প্রয়োজন রোলব্যাকের জন্য। একটি 50 ক সারি মুছা 10 মি সারি মুছার চেয়ে কম সংস্থান / স্থান নেয়। অবশ্যই, লগ ব্যাকআপগুলি এখনও ইত্যাদি চালায় এবং স্থান নেয় তবে সার্ভারে বড় মিকিংয়ের চেয়ে প্রচুর ছোট ব্যাচগুলিতে সহজ।
জিবিএন

1
ধন্যবাদ, ব্যাচ মোছা কিছুটা সাহায্য করে, আমার ধারণা এটি সর্বোত্তম বিকল্প।
tseau

2
@ ফিল হেলমার: যদি ব্যাচ মুছতে কোনও লেনদেন হয় তবে এটির কোনও লাভ নেই। অন্যথায় প্রতিটি লগ
রাইটিং

1
আরও একটি মন্তব্য: ব্যাচ মোছা বিপুলভাবে সহায়তা করে এবং 20 মিলিয়ন সারিগুলি 1 ঘন্টা 42 মিনিট থেকে 3 মিনিটের মধ্যে মুছে ফেলবে - তবে নিশ্চিত করুন যে টেবিলটির একটি ক্লাস্টার্ড সূচক রয়েছে! যদি এটি একটি স্তূপ হয়, টপ ক্লজটি কার্যকরকরণ পরিকল্পনার মধ্যে একটি ধরণের তৈরি করে যা কোনও উন্নতিকে অস্বীকার করে। পরে সুস্পষ্ট বলে মনে হচ্ছে।
tusau

2
@ নোমানন: এটি নিশ্চিত করে যে @ ROWCOUNT 1
জিবিএন

21

এটি টপ ক্লজটি সহজেই সম্পন্ন করতে আপনি ব্যবহার করতে পারেন:

WHILE (1=1)
BEGIN
    DELETE TOP(1000) FROM table
    IF @@ROWCOUNT < 1 BREAK
END

কোঁকড়া বন্ধনীগুলি আপনার কোডটি ফর্ম্যাট করে
gbn

@gbn এটি এসও তে আছে। এখানে এটি এখনও
01010

7

আপনি যদি মুছে ফেলা বাছাই করতে সক্ষম না হন তবে আপনার মুছে ফেলা বাছাই করার পরামর্শগুলির সাথে আমি সম্মত এবং এর মৌলিকতার জন্য ড্রপ / প্রস্তাবনাটি আমি পছন্দ করি তবে আমি আপনার প্রশ্নের নিম্নলিখিত মন্তব্যে আগ্রহী:

এটি মূলত একটি ট্র্যাঙ্কেল টেবিল বিবরণের সমতুল্য - বাদে আমাকে ট্র্যাঙ্কেট ব্যবহার করার অনুমতি নেই

আমি এই বিধিনিষেধের কারণটি সুরক্ষার সাথে সম্পর্কিত যা কোনও টেবিলকে সরাসরি কাটাতে দেওয়া দরকার এবং এই বিষয়টি যে আপনি যার সাথে সম্পর্কিত সেগুলি ছাড়া অন্য কোনও টেবিলগুলি কেটে ফেলতে পারবেন with

কেসটি ধরে নিলে, আমি ভাবছি যদি সঞ্চিত পদ্ধতি তৈরি করা হয় যা ট্র্যাঙ্কেট টেবিল ব্যবহার করে এবং "এক্সকিউটি এএস" ব্যবহার করে তবে টেবিলটি সরাসরি কাটানোর জন্য সুরক্ষা অধিকার প্রদানের একটি কার্যকর বিকল্প হিসাবে বিবেচিত হবে।

আশা করি, আপনার সংস্থার db_ddladmin ভূমিকাতে আপনার অ্যাকাউন্ট যুক্ত করার সাথে আপনার সংস্থার যে সুরক্ষা উদ্বেগ রয়েছে তার সমাধান করার সময় এটি আপনাকে প্রয়োজনীয় গতি প্রদান করবে।

এইভাবে সঞ্চিত প্রক্রিয়াটি ব্যবহার করার আরেকটি সুবিধা হ'ল সঞ্চিত পদ্ধতিটি নিজেই লক হয়ে যেতে পারে যাতে কেবল নির্দিষ্ট অ্যাকাউন্ট (গুলি) এটি ব্যবহারের অনুমতি পায়।

যদি কোনও কারণে এটি গ্রহণযোগ্য সমাধান না হয় এবং আপনার এই টেবিলের ডেটা সরিয়ে ফেলতে হবে এমন একটি জিনিস যা দিনে / ঘন্টা / ইত্যাদির জন্য একবার করা দরকার, আমি অনুরোধ করব যে কোনও এসকিউএল এজেন্ট কাজ টেবিলটি কেটে ফেলার জন্য তৈরি করা হয়েছিল I প্রতিদিন নির্ধারিত সময়ে

আশাকরি এটা সাহায্য করবে!


5

কাটা কাটা ব্যতীত .. কেবলমাত্র ব্যাচগুলিতে মুছে ফেলা আপনাকে সহায়তা করতে পারে।

আপনি টেবিলটি ফেলে রেখে পুনরায় তৈরি করতে পারেন, অবশ্যই সমস্ত সীমাবদ্ধতা এবং সূচি রেখে off ম্যানেজমেন্ট স্টুডিওতে আপনার কাছে টেবিলটি ড্রপ এবং তৈরি করতে স্ক্রিপ্ট করার বিকল্প রয়েছে, সুতরাং এটি একটি তুচ্ছ বিকল্প হতে হবে। তবে কেবলমাত্র যদি আপনাকে ডিডিএল ক্রিয়া করার অনুমতি দেওয়া হয় তবে আমি দেখতে পাচ্ছি যে এটি সত্যিকারের কোনও বিকল্প নয়।


কারণ অ্যাপ্লিকেশনটি সমবর্তী ক্রিয়াকলাপগুলির জন্য নকশাকৃত, কাঠামোর (ডিডিএল) পরিবর্তন এবং ট্র্যাঙ্কেট ব্যবহার করা বিকল্প নয় ... আমার ধারণা ব্যাচ ডিলিটটি সর্বোত্তম উপলব্ধ। ধন্যবাদ যদিও.
tuseau

1

যেহেতু এই প্রশ্নটি একটি গুরুত্বপূর্ণ রেফারেন্স তাই আমি এই কোডটি পোস্ট করছি যা আমাকে লুপের সাথে মুছতে এবং অগ্রগতি ট্র্যাক করার জন্য একটি লুপের মধ্যে বার্তাপ্রেরণ বুঝতে সহায়তা করেছিল।

এই সদৃশ প্রশ্ন থেকে ক্যোয়ারী পরিবর্তন করা হয়েছে । ক্যোয়ারী বেসের জন্য @RLF- তে ক্রেডিট ।

CREATE TABLE #DelTest (ID INT IDENTITY, name NVARCHAR(128)); -- Build the test table
INSERT INTO #DelTest (name) SELECT name FROM sys.objects;  -- fill from system DB
SELECT COUNT(*) TableNamesContainingSys FROM #deltest WHERE name LIKE '%sys%'; -- check rowcount
go
DECLARE @HowMany INT;
DECLARE @RowsTouched INT;
DECLARE @TotalRowCount INT;
DECLARE @msg VARCHAR(100);
DECLARE @starttime DATETIME 
DECLARE @currenttime DATETIME 

SET @RowsTouched = 1; -- Needs to be >0 for loop to start
SET @TotalRowCount=0  -- Total rows deleted so far is 0
SET @HowMany = 5;     -- Variable to choose how many rows to delete per loop
SET @starttime=GETDATE()

WHILE @RowsTouched > 0
BEGIN
   DELETE TOP (@HowMany)
   FROM #DelTest 
   WHERE name LIKE '%sys%';

   SET @RowsTouched = @@ROWCOUNT; -- Rows deleted this loop
   SET @TotalRowCount = @TotalRowCount+@RowsTouched; -- Increment Total rows deleted count
   SET @currenttime = GETDATE();
   SELECT @msg='Deleted ' + CONVERT(VARCHAR(9),@TotalRowCount) + ' Records. Runtime so far is '+CONVERT(VARCHAR(30),DATEDIFF(MILLISECOND,@starttime,@currenttime))+' milliseconds.'
   RAISERROR(@msg, 0, 1) WITH NOWAIT;  -- Print message after every loop. Can't use the PRINT function as SQL buffers output in loops.  

END; 
SELECT COUNT(*) TableNamesContainingSys FROM #DelTest WHERE name LIKE '%sys%'; -- Check row count after loop finish
DROP TABLE #DelTest;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.