
اگر با Oracle Database کار میکنی و تا حالا Execution Plan رو دیدهای اما دقیق نفهمیدهای چرا Oracle یک مسیر خاص را انتخاب کرده، این مقاله دقیقاً برای تو نوشته شده است.
در این مقاله آموزش اوراکل در بخش آموزش بهینه سازی کوئری، Access Path های Oracle را:
- به زبان ساده
- با مثالهای واقعی
- و با نگاه Performance & Tuning
بررسی میکنیم؛ طوری که بعد از خواندنش، Execution Plan دیگر برایت ترسناک نیست.
SQL Tuning در Oracle یعنی دیدن این واقعیتها از طریق فایلها و ابزارهای درست. پیشنهاد می کنم این مقاله زیر رو حتما مطالعه کنی.
در این مقاله شما می خوانید
Access Path یعنی:
روشی که Oracle برای رسیدن به دادهها از جدول یا ایندکس انتخاب میکند
Oracle Optimizer قبل از اجرای Query بررسی میکند:
- چند ردیف لازم داریم؟
- آیا ایندکس وجود دارد؟
- کدام مسیر I/O و CPU کمتری دارد؟
و در نهایت بهترین (از نظر خودش!) مسیر را انتخاب میکند.
🔹 تعریف
Oracle کل جدول را بلاک به بلاک میخواند، بدون توجه به وجود ایندکس.
🔹 چه زمانی اتفاق میافتد؟
- جدول کوچک است
- درصد زیادی از دادهها نیاز است
- شرط WHERE ایندکسپذیر نیست
- Optimizer تشخیص بدهد FTS سریعتر است
🔹 مثال
SELECT *
FROM employees
WHERE salary > ۱۰۰۰;
اگر اکثر رکوردها شرط را داشته باشند: ➡ Full Table Scan
✅ نکته مهم
Full Table Scan همیشه بد نیست!
در Data Warehouse و Queryهای سنگین، حتی بهترین انتخاب است.
۲.۱ 🔹 Index Unique Scan
سریعترین مسیر ممکن!
مثال
SELECT *
FROM employees
WHERE employee_id = 101;
شرط:
employee_idکلید اصلی یا Unique Index
۲.۲ 🔹 Index Range Scan
وقتی بازهای از دادهها را میخواهیم:
SELECT *
FROM employees
WHERE salary BETWEEN 5000 AND 7000;
کاربرد
- BETWEEN
, < , >= , <=
- LIKE ‘ABC%’
۲.۳ 🔹 Index Range Scan Descending
برای ORDER BY DESC:
SELECT *
FROM employees
ORDER BY hire_date DESC;
۲.۴ 🔹 Index Full Scan
Oracle کل ایندکس را میخواند (نه جدول).
SELECT employee_id
FROM employees
ORDER BY employee_id;
✅ مرتبسازی حذف میشود.
۲.۵ 🔹 Index Fast Full Scan (IFFS)
مثل Full Table Scan، اما روی ایندکس!
SELECT COUNT(employee_id)
FROM employees;
۲.۶ 🔹 Index Skip Scan
ایندکس مرکب، بدون استفاده از ستون اول!
CREATE INDEX idx_emp_dept_job
ON employees(department_id, job_id);
SELECT *
FROM employees
WHERE job_id = 'IT_PROG';
✅ هوشمند
❌ همیشه بهترین انتخاب نیست
بعد از Index Scan:
➡ Oracle با ROWID مستقیم به سراغ رکورد میرود.
INDEX RANGE SCAN
TABLE ACCESS BY INDEX ROWID
✅ سریعترین دسترسی فیزیکی به جدول
مناسب Data Warehouse، نه OLTP!
🔹 Bitmap Index Scan
🔹 Bitmap Merge
🔹 Bitmap Conversion to ROWID
مثال:
WHERE region = 'EU'
AND channel = 'ONLINE';
در Table Cluster چند جدول مرتبط کنار هم ذخیره میشوند.
مثال
SELECT *
FROM emp e, dept d
WHERE e.deptno = d.deptno;
✅ کاهش I/O در Joinهای پرتکرار
🔹 Partition Pruning
SELECT *
FROM sales
WHERE sales_date BETWEEN
DATE '2024-01-01' AND DATE '2024-01-31';
فقط پارتیشن مربوطه خوانده میشود ✅
۷.۱ 🔹 Nested Loop Join
- یک جدول کوچک
- ایندکس روی جدول بزرگ
➡ مناسب OLTP
۷.۲ 🔹 Hash Join
- دیتای زیاد
- بدون ایندکس
۷.۳ 🔹 Sort Merge Join
- Range Join
- Non Equality Join
خواندن مستقیم بلاکها بدون Buffer Cache
✅ Parallel Query
✅ Bulk Scan
سوالات متداول درباره Access Path در اوراکل
این یکی از پرتکرارترین سوالات Oracle است و برخلاف تصور رایج، همیشه نشانهی مشکل نیست.
Oracle زمانی Full Table Scan (FTS) را انتخاب میکند که:
- درصد زیادی از رکوردهای جدول نیاز باشد
- شرط WHERE ایندکسپذیر نباشد (مثلاً توابع روی ستون)
- ایندکس Selectivity پایینی داشته باشد
- آمار (Statistics) قدیمی یا نادرست باشد
- Optimizer تشخیص دهد FTS ارزانتر از Index Scan است
🔍 نکته مهم:
در Queryهای تحلیلی و Data Warehouse، Full Table Scan اغلب بهترین انتخاب است و حتی سریعتر از Index Scan عمل میکند.
این دو بسیار اشتباه گرفته میشوند، اما کاربردشان کاملاً متفاوت است.
Index Range Scan
- بخشی از ایندکس خوانده میشود
- ترتیب ایندکس حفظ میشود
- معمولاً همراه با WHERE شرطدار استفاده میشود
Index Fast Full Scan
- کل ایندکس خوانده میشود
- ترتیب ایندکس حفظ نمیشود
- شبیه Full Table Scan است ولی سریعتر
- بسیار مناسب برای COUNT و Aggregateها
📌 مثال رایج:
SELECT COUNT(*) FROM employees;
معمولاً با Index Fast Full Scan اجرا میشود.
در سیستمهای OLTP (تراکنشمحور)، هدف این است که:
📉 کمترین I/O
⚡ سریعترین پاسخ
🎯 کوچکترین Result Set
به همین دلیل بهترین ترکیب معمولاً این است:
- Index Unique Scan یا Index Range Scan
- به همراه Nested Loop Join
- با استفاده از Table Access by ROWID
✅ این ترکیب باعث میشود Oracle فقط همان رکوردهای لازم را بخواند، نه کل جدول.
💡 اگر در OLTP زیاد Full Table Scan میبینی، معمولاً جای بهینهسازی وجود دارد.
برای دیدن Access Path واقعی، باید Execution Plan را بررسی کنی.
سادهترین روش:
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE employee_id = 100;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
یا در اجراهای واقعی:
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);
در Execution Plan به این موارد توجه کن:
- Full Table Scan یا Index Scan؟
- نوع Index (Range / Unique / Fast Full)؟
- Join Method چیست؟
- Partition Pruning انجام شده یا نه؟
✅ کسی که Execution Plan را درست بخواند، عملاً SQL Tuning را بلد است.
جمعبندی
اگر بخواهی Execution Plan را درست بفهمی:
- Full Scan یا Index؟
- اگر Index → کدام نوع؟
- Join Method چیست؟
- Partition Pruning داریم یا نه؟
- ROWID چقدر تکرار شده؟
اینجاست که از یک کاربر Oracle به متخصص Performance Tuning تبدیل میشوی.
📥 اگر سوالی داری در مورد Access Path در اوراکل داری، در بخش کامنتها بپرس.
سؤالی درباره این مقاله داری؟
اگر نکتهای در این مقاله برات مبهم بود یا خواستی بیشتر بدونی، همین حالا برام بنویس تا دقیق و صمیمی پاسخت رو بدم — مثل یه گفتوگوی واقعی 💬
برو به صفحه پرسش و پاسخ
دیدگاهتان را بنویسید