ESC را فشار دهید تا بسته شود

زمیوس آموزش، یادگیری و سرگرمی

حذف رکوردهای تکراری در Oracle SQL | سریع‌ترین و بهینه‌ترین روش‌ها

حذف رکوردهای تکراری در Oracle SQL: راهنمای جامع

حذف رکوردهای تکراری یکی از چالش‌های مهم در پایگاه داده‌های Oracle SQL است.

در جداولی که میلیون‌ها رکورد دارند، وجود داده‌های تکراری باعث افزایش حجم پایگاه داده و کاهش کارایی Queryها می‌شود.

در این مقاله آموزش Oracle، بهترین روش‌های حذف رکوردهای تکراری در اوراکل را معرفی می‌کنیم تا پایگاه داده شما بهینه‌تر و سریع‌تر عمل کند.

اگر می خواهید در مورد مفاهیم ACID در اوراکل بیشتر آشنا بشید نوشته زیر را مطالعه کنید:

در این نوشته شما می خوانید

چرا حذف رکوردهای تکراری در SQL اهمیت دارد؟

  • کاهش حجم دیتابیس: ذخیره داده‌های اضافی، مصرف منابع سرور را افزایش می‌دهد.
  • افزایش کارایی جستجوها: داده‌های تکراری باعث کاهش سرعت Query Execution می‌شوند.
  • بهبود یکپارچگی داده‌ها: حذف داده‌های اضافی باعث جلوگیری از تناقضات اطلاعاتی در گزارش‌گیری می‌شود.

روش‌های حذف رکوردهای تکراری در Oracle SQL

در اینجا ۴ روش پرکاربرد برای حذف داده‌های تکراری در اوراکل را بررسی می‌کنیم.

✅ روش ۱: حذف رکوردهای تکراری با ROWID (بهترین عملکرد در جداول بزرگ)

این روش سریع‌ترین و کارآمدترین روش برای حذف داده‌های تکراری است.

				
					DELETE FROM employees
WHERE ROWID NOT IN (
    SELECT MIN(ROWID)
    FROM employees
    GROUP BY name, department, salary
);
				
			

🔹 این کد چه کار می‌کند؟

  • GROUP BY name, department, salary داده‌های مشابه را گروه‌بندی می‌کند.
  • MIN(ROWID) اولین رکورد از هر گروه را نگه می‌دارد.
  • بقیه رکوردهای تکراری حذف می‌شوند.

مزیت: سریع‌ترین روش برای جداول حجیم
محدودیت: در جداول بدون ROWID (مثلاً جداول External) قابل استفاده نیست.

✅ روش ۲: حذف رکوردهای تکراری با ()ROW_NUMBER

اگر نیاز دارید که کنترل بیشتری روی حذف رکوردها داشته باشید، از ROW_NUMBER() استفاده کنید.

				
					WITH duplicates AS (
    SELECT ROWID AS rid, 
           ROW_NUMBER() OVER (PARTITION BY name, department, salary ORDER BY ROWID) AS rn
    FROM employees
)
DELETE FROM employees WHERE ROWID IN (
    SELECT rid FROM duplicates WHERE rn > ۱
);

				
			

🔹 چرا از ()ROW_NUMBER استفاده کردیم؟

  • این تابع به هر گروه از رکوردهای مشابه شماره می‌دهد.
  • rn = 1 نگه داشته شده و بقیه حذف می‌شوند.

مزیت: امکان حذف بر اساس اولویت خاص
محدودیت: نسبت به روش ROWID کمی کندتر است.

✅ روش ۳: حذف رکوردهای تکراری با SELECT DISTINCT (ایجاد جدول جدید بدون داده‌های تکراری)

اگر جدول بسیار حجیم باشد و حذف با DELETE کند باشد، می‌توان از یک جدول جدید استفاده کرد:

				
					CREATE TABLE employees_new AS 
SELECT DISTINCT * FROM employees;

DROP TABLE employees;

ALTER TABLE employees_new RENAME TO employees;
				
			

مزیت: سریع‌ترین روش برای پاک‌سازی حجم زیادی از داده‌ها
محدودیت: نیاز به حذف و جایگزینی جدول دارد.

✅ روش ۴: حذف رکوردهای تکراری با MERGE INTO (روش پیشرفته و بهینه‌سازی شده)

				
					MERGE INTO employees e USING (
    SELECT MIN(ROWID) AS rid
    FROM employees
    GROUP BY name, department, salary
) keep_rows
ON (e.ROWID = keep_rows.rid)
WHEN NOT MATCHED THEN
    DELETE;

				
			

مزیت: ترکیب قدرت DELETE و MERGE برای حذف داده‌های اضافی
محدودیت: پیچیده‌تر از روش‌های دیگر است.

کدام روش برای حذف رکوردهای تکراری در Oracle SQL بهتر است؟

روش مزایا معایب
ROWID سریع‌ترین و بهینه برای جداول بزرگ محدود به جداولی با `ROWID`
()ROW_NUMBER کنترل دقیق‌تر روی حذف رکوردها کندتر از `ROWID`
CREATE TABLE AS SELECT DISTINCT بهترین گزینه برای حذف دسته‌ای نیاز به بازسازی جدول
MERGE INTO بهینه و مناسب برای دیتابیس‌های سازمانی پیچیده‌تر برای پیاده‌سازی

نکات کلیدی برای جلوگیری از ورود داده‌های تکراری در اوراکل

برای جلوگیری از ورود داده‌های تکراری در آینده، می‌توانید از موارد زیر استفاده کنید:

🔹 ۱. تعریف کلید اصلی (PRIMARY KEY) یا UNIQUE

				
					ALTER TABLE employees ADD CONSTRAINT unique_employee UNIQUE (name, department, salary);

				
			

این کار باعث می‌شود که اوراکل به‌طور خودکار مانع از ورود داده‌های تکراری شود.

🔹 ۲. استفاده از INSERT IGNORE یا MERGE INTO برای ورود داده‌ها

				
					MERGE INTO employees e
USING (SELECT 'Ali' name, 'IT' department, 5000 salary FROM dual) new_data
ON (e.name = new_data.name AND e.department = new_data.department AND e.salary = new_data.salary)
WHEN NOT MATCHED THEN 
    INSERT (name, department, salary) VALUES (new_data.name, new_data.department, new_data.salary);

				
			

این روش فقط داده‌های جدید را وارد می‌کند و از تکرار جلوگیری می‌کند.

سوالات متداول درباره حذف رکوردهای تکراری در اوراکل

اگر جدول میلیون‌ها رکورد دارد، استفاده از ROWID بهترین گزینه است.

این روش با DELETE WHERE ROWID NOT IN (SELECT MIN(ROWID) ... GROUP BY ...) سریع‌ترین عملکرد را دارد.

می‌توان از ()ROW_NUMBER استفاده کرد تا برای هر گروه از داده‌های تکراری شماره‌گذاری شود و سپس مواردی که rn > 1 دارند حذف شوند.

مثال:

WITH duplicates AS (
SELECT ROWID AS rid, ROW_NUMBER() OVER (PARTITION BY column1, column2 ORDER BY ROWID) AS rn
FROM your_table
)
DELETE FROM your_table WHERE ROWID IN (SELECT rid FROM duplicates WHERE rn > 1);

بله، با استفاده از MERGE INTO می‌توان رکوردهای اضافی را حذف کرد بدون اینکه نیاز به ساخت یک جدول جدید باشد.

این روش برای پایگاه داده‌های سازمانی توصیه می‌شود.

بهترین راه این است که روی ستون‌های مربوطه یک محدودیت UNIQUE اعمال کنید تا اوراکل اجازه ورود داده‌های تکراری را ندهد:

ALTER TABLE employees ADD CONSTRAINT unique_employee UNIQUE (name, department, salary);

همچنین، استفاده از MERGE INTO یا INSERT IGNORE در هنگام درج داده‌ها می‌تواند از تکرار جلوگیری کند.

نتیجه‌گیری

  • اگر جدول بسیار بزرگ است: ROWID بهترین روش برای حذف داده‌های تکراری است.
  • اگر نیاز به حذف دقیق‌تر دارید: ROW_NUMBER() انتخاب بهتری است.
  • اگر نیاز به حذف سریع حجم زیادی از داده‌ها دارید: SELECT DISTINCT با ایجاد جدول جدید پیشنهاد می‌شود.
  • اگر بخواهید حذف را بهینه‌سازی کنید: MERGE INTO یک گزینه حرفه‌ای است.

🔥 با این روش‌ها، پایگاه داده‌ی Oracle شما سریع‌تر، بهینه‌تر و منظم‌تر خواهد شد.

🔽 نظر شما چیست؟ آیا روش خاصی برای حذف داده‌های تکراری استفاده می‌کنید؟ در کامنت‌ها تجربیات خود را به اشتراک بگذارید!

میثم راد

من یه برنامه نویسم که حسابی با دیتابیس اوراکل رفیقم! از اونایی ام که تا چیزی رو کامل نفهمم،ول کن نیستم، یادگرفتن برام مثل بازیه، و نوشتن اینجا کمک می کنه تا چیزایی که یاد گرفتم رو با بقیه به شریک بشم، با هم پیشرفت کنیم.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *