سؤال

أنا باستخدام استعلام SQL مشابهة الشكل التالي:

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.person_uid = table2.person_uid
AND table1.period = table2.period

و إما الطريقة بطيئة جدا أو شيء ما أصاب بالجمود لأنه يأخذ ما لا يقل عن 4 دقائق للعودة.إذا كنت تغييره إلى هذا:

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.person_uid = table2.person_uid
WHERE table1.period = table2.period

ثم أنه يعمل بشكل جيد (وإن لم يكن العودة حق عدد من الأعمدة).هل هناك أي طريقة لتسريع هذا ؟

التحديث:يفعل الشيء نفسه إذا كنت التبديل آخر سطرين من هذا الأخير الاستعلام:

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.period = table2.period
WHERE table1.person_uid = table2.person_uid

تحديث 2: في الحقيقة هذه الآراء التي سأنضم.للأسف أنهم على قاعدة البيانات لا نملك التحكم, لذلك لا أستطيع (بسهولة) إجراء أية تغييرات على الفهرسة.أنا أتفق أن هذه الفهرسة القضية بالرغم من ذلك.سأنتظر قليلا قبل قبول إجابة في حال كان هناك بعض طريقة سحرية لضبط هذا الاستعلام التي لا تعرف عن.وإلا سوف يقبل أحد الأجوبة في محاولة لمعرفة طريقة أخرى لفعل ما أريد القيام به.شكرا على مساعدة الجميع حتى الآن.

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

المحلول

نضع في اعتبارنا أن البيانات 2 و 3 تختلف عن الأولى.

كيف ؟ حسنا, أنت تقوم left join الخاص بك حيث شرط ليس أخذ ذلك في الاعتبار (مثل على شرط لا).على الأقل حاول أن:

SELECT col1, col2
FROM table1, table2
WHERE table1.person_uid = table2.person_uid (+)
AND table1.period = table2.period (+)

وانظر إذا كان يمكنك الحصول على نفس الأداء المسألة.

ما المؤشرات التي لديك على هذه الجداول ؟ هو هذه العلاقة يحددها قيد المفتاح الخارجي?

ما كنت تحتاج على الأرجح هو مؤشر مركب على كل person_uid و الفترة (على كل الجداول).

نصائح أخرى

أعتقد أنك بحاجة إلى أن نفهم لماذا الماضيين ليست نفس الاستعلام الأول.إذا كنت تفعل left join ثم إضافة جملة where referncing حقل في الجدول على الجانب الأيمن من الانضمام إلى (الذي قد لا دائما يكون لديك سجل لتتناسب مع الجدول الأول) ، ثم عليك تغيير فعال في الانضمام إلى صلة داخلية.هناك استثناء واحد لهذا وهذا إذا كان لك مرجع شيء مثل

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.person_uid = table2.person_uid
WHERE table2.person_uid is null

في هذه الحالة كنت طالبا للعلم الذي لم يكن لديك سجل في الجدول الثاني.ولكن بخلاف هذه الحالة الخاصة ، يتم تغيير اليسار الانضمام إلى inner join إذا كنت refence حقل في table2 في جملة where.

إذا كان الاستعلام الخاص بك ليست سريعة بما فيه الكفاية ، وأود أن ننظر في الفهرسة.

أي شيء يقوله لك أي شخص على أساس المعلومات التي قدمتها هو تخمين.

ننظر في تنفيذ خطة الاستعلام.إذا كنت لا ترى سبب البطء في خطة ما بعد الخطة هنا.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009

هل لديك تغطي مؤشرات على person_uid و period لكل من الجداول ؟

إذا كنت لا تضيف لهم وحاول مرة أخرى.

نلقي نظرة على خطة التنفيذ ومعرفة ما الاستعلام يقوم به في الواقع.

أيضا:ما هي أنواع البيانات من الحقول ؟ هم نفس في كل من الجداول ؟ ضمني يمكن أن يلقي حقا إبطاء الأمور.

هل هذه الجداول والفهارس على أعمدة أنت للانضمام ؟ تثبيت أوراكل مجانا SQLDeveloper المنتج واستخدامه للقيام "شرح" على هذا الاستعلام ومعرفة ما إذا كان فعل متسلسلة بفحص من كلا الجدولين.

في اليسار الانضمام ستكون المسح جدول1 لكل مزيج فريد من (person_uid الفترة) ثم البحث table2 لجميع السجلات المقابلة هناك.إذا table2 لا يكون مناسبا مؤشر, وهذا يمكن أن تنطوي على مسح كل هذا الجدول أيضا.

أفضل تخمين ، دون رؤية خطة التنفيذ ، هو أن الاستعلام الأول (الوحيد الذي يبدو أن يكون صحيحا) هو الحاجة إلى مسح الجدول table2 وكذلك جدول1.

كما كنت أقول أنه لا يمكنك تغيير الفهارس, كنت بحاجة إلى تغيير الاستعلام.بقدر ما أستطيع أن أقول, هناك واحد فقط بديل...

SELECT
   col1, col2
FROM
   table2
FULL OUTER JOIN
   table1
      ON table1.person_uid = table2.person_uid
      AND table1.period = table2.period
WHERE
   table1.person_uid IS NOT NULL

الأمل هنا هو أنه يمكنك مسح table2 لكل مزيج فريد من (person_uid,), لكن الاستفادة من الفهارس على جدول1.(بدلا من المسح جدول1 و الاستفادة من الفهارس على table2 التي ما كنت أتوقع من الاستعلام الخاص بك.)

إذا جدول1 لا يكون مناسبا الفهارس ، ومع ذلك ، سوف يكون من المستبعد جدا أن نرى أي تحسن الأداء في جميع...

الديمقراطيين.

في واحدة من التحديثات المهمة أنه هو في الواقع الاستعلام على الجداول.في هذه الحالة الأداء يمكن أن يكون جيدا بنسبة مباشرة الاستعلام عن الجداول يحتاج خصوصا إذا كانت الآراء مجمع والانضمام إلى العديد من الجداول الأخرى التي لا تحتوي على المعلومات التي يحتاجها أو أنها هي الآراء التي تدعو وجهات النظر.

ANSI الانضمام إلى جملة جدا تمييز واضح بين الانضمام إلى ظروف تصفية المسندات;وهذا مهم جدا عند كتابة صلات خارجية.باستخدام emp/قسم الجداول ننظر إلى النتائج التالية اثنين صلات خارجية

Q1

SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
LEFT OUTER JOIN emp e
on  d.deptno = e.deptno
and loc in ('NEW YORK','BOSTON' )
;

DNAME              DEPTNO ENAME             MGR LOC
-------------- ---------- ---------- ---------- -------------
ACCOUNTING             10 CLARK            7839 NEW YORK
ACCOUNTING             10 KING                  NEW YORK
ACCOUNTING             10 MILLER           7782 NEW YORK
RESEARCH               20                       DALLAS
SALES                  30                       CHICAGO
OPERATIONS             40                       BOSTON

====

Q2
SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
LEFT OUTER JOIN emp e
on  d.deptno = e.deptno
where loc in ('NEW YORK','BOSTON' )
;

DNAME              DEPTNO ENAME             MGR LOC
-------------- ---------- ---------- ---------- -------------
ACCOUNTING             10 CLARK            7839 NEW YORK
ACCOUNTING             10 KING                  NEW YORK
ACCOUNTING             10 MILLER           7782 NEW YORK
OPERATIONS             40                       BOSTON

المثال الأول ، Q1 يظهر مثال على "الانضمام على ثابت".أساسا, في حالة تصفية يتم تطبيقها قبل أداء الخارجي الانضمام.لذلك يمكنك إزالة الصفوف التي يتم بعد ذلك إضافة كجزء من صلة خارجية.انها ليست بالضرورة خاطئة ، ولكن هل هذا الاستعلام أنك طلبت حقا ؟ في كثير من الأحيان هو النتائج الموضحة في Q2 المطلوبة ، حيث يتم تطبيق عامل التصفية بعد (الخارجي) الانضمام.

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

للمطورين الذين هم على دراية مع أوراكل الخارجي الانضمام إلى بناء جملة الاستعلام ربما كانت مكتوبة كما

SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
        ,emp e
where  d.deptno = e.deptno(+)
and loc in ('NEW YORK','BOSTON' )

هذا الاستعلام هو لغويا أي Q2 أعلاه.

هكذا وباختصار ، فإنه من المهم للغاية أن تفهم مختلفة بين الانضمام إلى الشرط و جملة WHERE عند كتابة ANSI صلات خارجية.

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