كيف يمكنني اختيار تلميحات مختلفة للوصول المختلفة لجدول واحد في تلميح الاستعلام؟

StackOverflow https://stackoverflow.com/questions/2524248

سؤال

افترض أن لدي الاستعلام التالي:

select * from A, B, C, D
where A.x = B.x
and B.y = C.y
and A.z = D.z

لدي فهارس على AX و BX و BY و CY و DZ

لا يوجد فهرس على AZ

كيف يمكنني إعطاء تلميح لهذا الاستعلام لاستخدام تلميح فهرس على الفأس ولكن تلميح use_hash على AZ؟ يبدو أن التلميحات تأخذ اسم الجدول فقط ، وليس الانضمام المحدد ، لذلك عند استخدام جدول واحد مع توصيلات متعددة ، لا يمكنني سوى تحديد استراتيجية واحدة لها.

بديل ، لنفترض أنني أستخدم تلميحًا رائدًا أو مرتبة على الاستعلام أعلاه. كل من هذه التلميحات تأخذ فقط اسم الجدول أيضًا ، فكيف يمكنني التأكد من حدوث انضمام AX = BX قبل AZ = DZ واحد؟ أدرك في هذه الحالة أنه يمكنني القائمة D أولاً ، لكن تخيل D ينضم لاحقًا إلى E وأن De Join هو آخر مرة أريدها في الاستعلام بأكمله.

تكوين ثالث - لنفترض أنني أريد أن يكون انضمام الفأس هو الأول من الاستعلام بأكمله ، وأريد أن يكون انضمام AZ هو الأخير. كيف يمكنني استخدام تلميح للحصول على انضمام واحد من A ليتم ، يليه Join BC ، و Join AD LAST؟

هل كانت مفيدة؟

المحلول

بادئ ذي بدء ، يجب أن يكون استخدام مثل هذه التلميحات هو الملاذ الأخير ، وليس طريقة عادية لكتابة الاستعلامات. في معظم الأوقات ، يجب عليك فقط التأكد من أن إحصائيات Optimiser محدثة وترك البنك المركزي العماني يعمل على العمل على المسار الأمثل لنفسه - هذا هو وظيفتها!

يمكن لتلميح الفهرس تحديد اسم الفهرس الذي تريد استخدامه مثل هذا:

SELECT /*+ INDEX (A, A_X_IDX) */ *
...

(على افتراض أن الفهرس على الفأس يسمى A_X_IDX).

لا يمكنك معرفة Oracle استخدام استخدام الفهرس على AX و استخدم انضمام التجزئة إلى الجدول A في نفس البيان ، وهذا لا معنى له. ومع ذلك ، يمكنك (إذا كان يجب عليك) تحديد مسار الوصول لكل جدول مثل:

SELECT /*+ INDEX (A, A_X_IDX) INDEX(B, B_Y_IDX) USE_HASH(C) */ *

ولكن للتكرار ، يجب أن يكون نادر للحاجة إلى القيام بذلك. استثمرت Oracle ملايين الدولارات ومانهور في تطوير CBO ، فلماذا إيقاف تشغيله بشكل فعال؟

نصائح أخرى

على SQL Server ، ستفعل تلميحًا مشتركًا مثل هذا

SELECT * FROM table1 t1
INNER hash join table2 t2 ON  t1.id = t2.id

ويمكنك أيضًا توفير تلميح فهرس

select * from table1 t1
inner  join table2 t2 with (index( bla))  on  t1.id = t2.id

لا أعرف كيف يبدو بناء الجملة في Oracle ، راجع للشغل لماذا تستخدم صلات النمط القديم؟ هل ما زلت في 8i؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top