سؤال

أعرف أن Oracle RDMS لا يمكنه دمج طريقة عرض لها مشغل مجموعة. أريد أن أعرف لماذا هذا.

على سبيل المثال ، هذا:

SELECT u.*
FROM
 (
  SELECT a.a1    A,
        a.a2    B
   FROM tab_a a
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b
)     u,
tab_p p
WHERE p.a = u.a

يمكن أن تتحول إلى هذا:

SELECT *
FROM
 (
  SELECT a.a1    A,
         a.a2    B
    FROM tab_a a,
         tab_p p
   WHERE p.a = a.a1
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b,
         tab_p p
   WHERE p.a = b.b1
)

هذان الاستفسارين متكافئان ، أليس كذلك؟ [تحرير

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

المحلول

التحول الذي تصفه في سؤالك المعدل يبدو صالحًا بالنسبة لي.

هناك العديد من التحويلات المختلفة للاستعلام التي يحملها Oracle Optimizer يمكن من الناحية النظرية أداء ، ولكن في الممارسة العملية يقتصر هذا على تلك التحولات التي يمتلكها فريق Oracle في الواقع أزعجت التنفيذ.

كل تحول ، إذا تمت إضافته ، سيتطلب استثمارًا كبيرًا في الترميز والاختبار ، وسيتم القيام به فقط إذا تم اكتشاف طلب كافٍ في سوق الدفع.

لذلك ، ليس الأمر "لا يمكن" ، بالضرورة ؛ انها فقط لا ، حتى الآن.

نصائح أخرى

ستنتج الاستعلامات نفس مجموعة النتائج ، ولكن من المحتمل أن تكون خطة التنفيذ مختلفة. أتوقع أن يكون الاستعلام الأول أكثر كفاءة لأنه يقارن tab_p مرة واحدة ، مقابل مرتين في الاستعلام الثاني.


في السابق ، استخدم كلا الاستعلامات المحددة *، لا يوجد اسم مستعار جدول في أي منهما.

لا ، هذه الاستفسارات ليست متكافئة.

الأول سيعود أعمدة من كل من الجدول المشتق (بيان الاتحاد) و tab_p الطاولة. سوف يعيد الاستعلام الثاني قيم فقط من الجدول المشتق (بيان الاتحاد) ، ولا توجد أعمدة من tab_p الطاولة. من الواضح إذا قمت باستبدال الأسماء المستعارة في مكان SELECT *:

الاستعلام الأول:

SELECT u.*, p.*
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u,
       tab_p p
 WHERE p.a = u.a

الاستعلام الثاني:

SELECT x.*
 FROM (SELECT a.a1    A,
              a.a2    B
         FROM tab_a a,
              tab_p p
        WHERE p.a = a.a
       UNION ALL
       SELECT b.b1    A,
              b.b2    B
         FROM tab_b b,
              tab_p p
        WHERE p.a = b.a) x

لا يوجد tab_p الأعمدة في جملة SELECT من الاستعلام الداخلي ، للحصول على الاستعلام الخارجي لتوفيره في ResultSet النهائي.

هذه:

SELECT *
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u
  JOIN tab_p p ON p.a = u.a

.. ما يعادل الاستعلام الأول. إنه يستخدم ANSI-92 Join Syntax مقابل بناء جملة ANSI-89 المستخدم في الاستعلام الأول.

أنها ليست مكافئة. سوف يفشل الاستعلام الثاني ، كما u غير محدد.

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