سؤال

أنا فضولي أي مما يلي سيكون أكثر كفاءة؟

لقد كنت دائمًا حذرًا بعض الشيء بشأن استخدامه IN لأنني أعتقد أن SQL Server يحول النتيجة المحددة إلى درجة كبيرة IF بيان. لمجموعة نتائج كبيرة ، قد يؤدي ذلك إلى ضعف الأداء. بالنسبة لمجموعات النتائج الصغيرة ، لست متأكدًا من أنه من الأفضل. لمجموعات النتائج الكبيرة ، لا تفعل ذلك EXISTS كن أكثر كفاءة؟

WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

ضد.

WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
هل كانت مفيدة؟

المحلول

EXISTS سيكون أسرع لأنه بمجرد أن يجد المحرك نجاحًا كبيرًا ، فإنه سيتوقف عن الظهور لأن الحالة قد أثبتت ذلك.

مع IN, ، سوف يجمع جميع النتائج من الاستيلاء الفرعي قبل مزيد من المعالجة.

نصائح أخرى

الإجابة المقبولة قصيرة النظر والسؤال فضفاض بعض الشيء في ذلك:

1) لا يذكر صراحة ما إذا كان مؤشر التغطية موجودًا في اليسار أو اليمين أو كلا الجانبين.

2) لا يأخذ أي منهما في الاعتبار حجم مجموعة المدخلات اليسرى ومجموعة الجانب الأيمن.
(السؤال يذكر فقط كبيرًا بشكل عام نتيجة تعيين).

أعتقد أن المحسن ذكي بما يكفي للتحويل بين "في" VS "موجود عندما يكون هناك اختلاف كبير في التكلفة بسبب (1) و (2) ، وإلا فقد يتم استخدامه فقط كتلميح (على سبيل المثال موجود لتشجيع استخدامه للاستخدام فهرس يمكن البحث عنه على الجانب الأيمن).

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

لقد أجريت بعض الاختبارات على SQL Server 2005 و 2008 ، وعلى كل من وجودها و in العودة مع نفس خطة التنفيذ الفعلية بالضبط ، كما ذكر الآخرون. المحسن الأمثل. قون

شيء يجب أن تكون على دراية به ، يمكن أن يعيد في بعض الأحيان نتائج مختلفة إذا لم تقم بتعليق استعلامك بشكل صحيح: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

سأذهب مع وجوده ، انظر الارتباط أدناه:

SQL Server: Join VS in VS موجود - الفرق المنطقي

عادةً ما تكون خطط التنفيذ متطابقة في هذه الحالات ، ولكن حتى ترى كيفية عوامل مُحسّن في جميع جوانب الفهارس الأخرى وما إلى ذلك ، فلن تعرف أبدًا.

لذلك ، في ليس هو نفسه كما هو موجود ولن ينتج نفس خطة التنفيذ.

عادةً ما يتم استخدامه في مسمة فرعية مرتبطة ، وهذا يعني أنك ستنضم إلى الاستعلام الداخلي الموجود مع استعلامك الخارجي. سيؤدي ذلك إلى إضافة المزيد من الخطوات لإنتاج نتيجة حيث تحتاج إلى حل صناديق الاستعلام الخارجي وينضم الاستعلام الداخلي ثم تطابق مع الجمل للانضمام إلى كليهما.

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

النظر في هذا:

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

  2. إذا كنت تستخدم ، فإن الانضمام إلى استعلامك الخارجي معقد (يستغرق المزيد من الوقت لأداء ، ولا فهارس مناسبة) ، فسوف يبطئ الاستعلام بعدد الصفوف في الجدول الخارجي ، وأحيانًا يمكن أن يكون الوقت المقدر لإكماله في أيام. إذا كان عدد الصفوف مقبولًا بالنسبة للأجهزة المعطاة ، أو أن يتمتع Cardinality للبيانات (على سبيل المثال ، يمكن أن تؤدي القيم المتميزة في مجموعة بيانات كبيرة) بشكل أسرع من وجودها.

  3. سيتم ملاحظة كل ما سبق عندما يكون لديك قدر لا بأس به من الصفوف على كل جدول (بشكل عادل أعني شيئًا يتجاوز معالجة وحدة المعالجة المركزية و/أو عتبات ذاكرة الوصول العشوائي للتخزين المؤقت).

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

الحيلة هي الحد من عدد الصفوف المراد مسحها.

يعتبر،

ماريانوك

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

لذا:

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

لأن المساع الفرعي المرتبط RBAR, ، النتيجة الأولى نجاح يجعل الشرط صحيحًا ، ولا تتم معالجته أكثر.

هناك العديد من إجابات الإجابات المضللة هنا ، بما في ذلك الإجابات التي تم الانتهاء منها للغاية (على الرغم من أنني لا أعتقد أن OPS تعني الضرر). الجواب القصير هو: هذه هي نفسها.

هناك العديد من الكلمات الرئيسية في لغة SQL (T-) ، ولكن في النهاية ، فإن الشيء الوحيد الذي يحدث بالفعل على الأجهزة هو العمليات كما هو موضح في خطة الاستعلام عن التنفيذ.

عملية العلائقية (نظرية الرياضيات) التي نقوم بها عندما نستدعي [NOT] IN و [NOT] EXISTS هو انضمام نصف (مضاد للانضمام عند استخدام NOT). ليس من قبيل الصدفة أن تقوم عمليات خادم SQL المقابلة نفس الاسم. لا توجد عملية تذكر IN أو EXISTS في أي مكان - فقط (مكافحة) نصف ينضم. هكذا، لا توجد طريقة تكافؤ منطقيا IN ضد EXISTS يمكن أن يؤثر الاختيار على الأداء لأن هناك طريقة واحدة والوحيدة ، وهي عملية تنفيذ شبه (مكافحة) الانضمام إلى نتائجها للحصول على نتائجها.

مثال:

الاستعلام 1 ( خطة )

select * from dt where dt.customer in (select c.code from customer c where c.active=0)

الاستعلام 2 ( خطة )

select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)

خارج الجزء العلوي من رأسي وليس مضمونًا أن أكون صحيحًا: أعتقد أن الثانية ستكون أسرع في هذه الحالة.

  1. في البداية ، من المحتمل أن يتسبب الاستماع الفرعي المرتبط في تشغيل الاسم الفرعي لكل صف.
  2. في المثال الثاني ، يجب أن يتم تشغيل الاستماع الفرعي مرة واحدة فقط ، لأنه غير مرتبط.
  3. في المثال الثاني ، IN سوف الدائرة القصيرة بمجرد العثور على تطابق.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top