لا يمكن دمج الاتحاد كل الرأي
-
26-09-2019 - |
سؤال
أعرف أن 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
غير محدد.