
مقدمه: چرا کوئری من کند شده؟
حتماً برات پیش اومده که یه Query ساده رو روی دیتای کم اجرا میکنی و عالیه، ولی همون Query وقتی روی دیتای زیاد یا تو سیستم اصلی اجرا میشه، کُند میشه یا حتی Timeout میده. دلیلش چیه؟
پاسخ در Execution Plan نهفتهست. Oracle همیشه تلاش میکنه بهترین مسیر رو برای اجرای کوئری انتخاب کنه، ولی در Queryهای پیچیده، این انتخاب همیشه درست نیست.
در این مقاله SQL Tuning و بهینه سازی کوئری هاست که باید با قدرتی به اسم Hint وارد عمل بشی.
اگر می خواهید در با مفهوم Execution Plan به صورت کاربردی آشنا بشید، نوشته زیر را مطالعه کنید:
در این نوشته شما می خوانید
Hint در Oracle SQL یعنی چی؟
Hint در واقع یه راهنمایی برای Optimizer اوراکله که توی کوئری بهش میگی:
«ببین، من بهتر میدونم از چی استفاده کنی!» 😄
و بهش دستور میدی که مثلاً:
- از Index خاصی استفاده کن
- ترتیب Joinها رو رعایت کن
- Subquery رو Merge نکن
- یا حتی از اجرای موازی استفاده کن
ساختار Hint کاملاً مثل یه کامنته، ولی فقط مخصوص Oracle:
SELECT /*+ HINT_NAME */ columns
FROM table_name;
دستهبندی Hintهای کاربردی و مهم
۱. کنترل روش Join در Query
Oracle چند روش داره برای Join بین جداول. با Hintها میتونی مشخص کنی از کدوم روش استفاده کنه:
| Hint | توضیح |
|---|---|
| USE_NL(table) | استفاده از Nested Loop Join |
| USE_HASH(table) | استفاده از Hash Join |
| USE_MERGE(table) | استفاده از Merge Join |
📌 مثال:
SELECT /*+ USE_HASH(e) */ e.empno, d.dname
FROM emp e
JOIN dept d ON e.deptno = d.deptno;
۲. تعیین ترتیب Joinها
با ORDERED به Oracle میگی که جداول رو دقیقاً به همون ترتیبی که تو FROM نوشتی Join کنه:
| مثال Hint | توضیح |
|---|---|
| ORDERED | اجبار به اجرای Join بر اساس ترتیب ذکر شده در FROM |
📌 مثال:
SELECT /*+ ORDERED */ ...
FROM orders o, products p
WHERE o.product_id = p.id;
۳. استفاده از Index به صورت دقیق
| Hint | کاربرد |
|---|---|
| INDEX(table index_name) | استفاده از Index مشخص |
| NO_INDEX(table) | نادیده گرفتن Index |
| INDEX_COMBINE(table) | ترکیب ایندکسها (مثلاً در Bitmap) |
📌 مثال کاربردی:
SELECT /*+ INDEX(emp emp_name_idx) */ *
FROM emp
WHERE ename = 'SCOTT';
۴. کنترل Subquery و Merge
در Queryهای پیچیده، Oracle ممکنه Subqueryها رو Merge کنه و ساختار کوئری رو عوض کنه. اینجا میتونی جلوی این کار رو بگیری:
📌 مثال:
SELECT /*+ NO_MERGE(sq) */ *
FROM (
SELECT * FROM emp
) sq
WHERE ROWNUM < 10;
۵. استفاده از Full Scan و اجرای موازی (Parallel)
| Hint | توضیح |
|---|---|
| FULL(table) | اجبار به Full Table Scan |
| PARALLEL(table, degree) | استفاده از اجرای موازی با تعداد پردازشگر مشخص |
| NOPARALLEL(table) | اجبار به اجرای غیرموازی |
📌 مثال:
SELECT /*+ FULL(sales) PARALLEL(sales, 4) */ *
FROM sales;
مثال کامل از بهینهسازی یک کوئری پیچیده
🎯 هدف:
نمایش فروشهایی که بالاتر از میانگین فروش کشور خودشون بودن، همراه با نام مشتری.
کوئری اولیه (بدون Hint):
SELECT c.name, s.country, s.amount
FROM sales s
JOIN customers c ON s.customer_id = c.id
WHERE s.amount > (
SELECT AVG(s2.amount)
FROM sales s2
WHERE s2.country = s.country
);
نسخه بهینهشده با Hint:
SELECT /*+ LEADING(s c) USE_HASH(c) NO_MERGE(subq) */
c.name, s.country, s.amount
FROM sales s
JOIN customers c ON s.customer_id = c.id
WHERE s.amount > (
SELECT /*+ FULL(s2) */ AVG(s2.amount)
FROM sales s2
WHERE s2.country = s.country
) subq;
در این نسخه:
- ترتیب Join کنترل شده (
LEADING) - از Hash Join استفاده شده
- Subquery از Merge شدن جلوگیری شده
- و یک Full Scan کنترلشده داریم برای بهینهسازی داخلی Subquery
چطور بفهمیم Hint واقعاً اثر کرده؟
از ابزار DBMS_XPLAN.DISPLAY استفاده کن:
EXPLAIN PLAN FOR
;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
نتیجه رو بررسی کن ببینی:
- Hash Join اعمال شده؟
- ترتیب Join رعایت شده؟
- از ایندکس خاصی استفاده شده؟
نکات حرفهای برای استفاده از Hint در Oracle
🔹 Hint رو فقط زمانی استفاده کن که مطمئن باشی Execution Plan بهینه نیست
🔹 هیچ وقت فقط به چشم یک “ترفند سریع” به Hint نگاه نکن—به چشم ابزار جراحی دقیق نگاهش کن
🔹 اگر آمار جدول بهروز نباشه (DBMS_STATS)، Hint هم ممکنه نادیده گرفته شه
🔹 همیشه قبل و بعد از اعمال Hint، Plan رو مقایسه کن
سوالات متداول درباره معماری استفاده از Hint در اوراکل
Hint در Oracle SQL به Optimizer پایگاه داده کمک میکند تا روش خاصی برای اجرای Query انتخاب کند.
به زبان ساده، با Hint به Oracle میگوییم که از کدام Index استفاده کند، کدام جدول را اول Join کند، یا چگونه Subqueryها را پردازش کند.
این ابزار برای بهینهسازی عملکرد Query در شرایط پیچیده بسیار مفید است.
USE_NL به Oracle میگوید از الگوریتم Nested Loop برای Join استفاده کند که برای دادههای کم مناسب است.در مقابل، USE_HASH باعث میشود از Hash Join استفاده شود که برای حجمهای بزرگتر و بدون ایندکس، بسیار سریعتر است. انتخاب درست بین این دو، تاثیر زیادی بر عملکرد کوئری دارد.
برای بررسی اجرای Hint، میتوان از دستور زیر استفاده کرد:
EXPLAIN PLAN FOR <your query>;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
اگر Hint اعمال شده باشد، در خروجی Execution Plan میتوانید Hash Join، Full Scan یا Index Scan موردنظر را ببینید. همچنین، در نسخههای جدیدتر Oracle، V$SQL_HINT هم برای بررسی Hintها قابل استفاده است.
خیر ❗ استفاده نادرست از Hint میتواند عملکرد را بدتر کند.
Hint زمانی مفید است که Optimizer بهدرستی شرایط دادهها و ایندکسها را درک نکند یا آماری قدیمی داشته باشد.
استفاده از Hint بدون بررسی Execution Plan میتواند منجر به انتخاب روشهای نامناسب و کند شدن کوئری شود.
نتیجهگیری: چرا و چطور از Hint استفاده کنیم؟
استفاده هوشمندانه از Hintها در Oracle میتونه کوئریهای سنگین رو چندین برابر سریعتر کنه، اما به شرطی که بدونیم کِی و کجا ازش استفاده کنیم.
در Queryهای پیچیده، ترکیب چندین Hint با بررسی دقیق Execution Plan میتونه راهگشا باشه و عملکرد سیستم رو در سطح Enterprise بهبود بده.
پس اگر با Queryهای کند، Timeout یا Full Table Scanهای غیرضروری درگیر هستی…
وقتشه از قدرت Hintها استفاده کنی و Queryهات رو به پرواز دربیاری 🚀
📢 نظر شما چیست؟ اگر شما هم اطلاعات و تجربه خوبی در استفاده از Hintها در بخش آموزش Oracle Database دارید خوشحال میشم در بخش نظرات، تجربه های ارزشمندتان را با ما به اشتراک بگذارید! 🚀
سؤالی درباره این مقاله داری؟
اگر نکتهای در این مقاله برات مبهم بود یا خواستی بیشتر بدونی، همین حالا برام بنویس تا دقیق و صمیمی پاسخت رو بدم — مثل یه گفتوگوی واقعی 💬
برو به صفحه پرسش و پاسخ
دیدگاهتان را بنویسید