هل من الأفضل ضم حقلين معًا أم مقارنتهما بنفس الثابت؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

على سبيل المثال أيهما أفضل:

select * from t1, t2 where t1.country='US' and t2.country=t1.country and t1.id=t2.id

أو

select * from t1, t2 where t1.country'US' and t2.country='US' and t1.id=t2.id

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

ملحوظة: Sybase، وهناك فهرس على كلا الجدولين country+id.

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

المحلول

لقد حدث لي موقف مشابه لهذا وكان الحل الذي لجأت إليه:

حدد * من T1 Inner Join T2 على t1.id = t2.id و t1.country = t2.country و t1.country = 'US'

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

نصائح أخرى

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

أنا شخصياً أفضل النموذج الأول:

حدد * من t1 وt2 حيث t1.country='US' وt2.country=t1.country وt1.id=t2.id

لأنه إذا أردت تغيير الحرفي فلا يلزم سوى تغيير واحد.

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

(التحسين المبكر هو أصل كل الشرور!)

من الممكن أنه إذا تمت فهرسة "t1.id" و"t2.id"، فإن محرك قاعدة البيانات يجمعهما معًا بناءً على تلك الحقول، ثم يستخدم بقية جملة WHERE لتصفية الصفوف.

يمكن فهرستها ولكن بجداول صغيرة بشكل لا يصدق، وكلاهما يتناسب مع صفحة من الذاكرة.في هذه الحالة، قد يقوم محرك قاعدة البيانات بإجراء فحص كامل لكليهما بدلاً من تحميل الفهرس.

أنت لا تعرف حقًا حتى تحاول.

ربما تعتمد الإجابة الصحيحة على محرك SQL الخاص بك.بالنسبة لـ MS SQL Server، من الواضح أن النهج الأول هو الأفضل لأن المُحسِّن الإحصائي يُعطى دليلًا إضافيًا قد يساعده في العثور على مسار دقة أفضل (أكثر مثالية).

أعتقد أن ذلك يعتمد على المكتبة ومحرك قاعدة البيانات.سيقوم كل واحد منهم بتنفيذ SQL بشكل مختلف، وليس هناك ما يشير إلى أي واحد سيتم تحسينه.

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

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

أظن أن هذا سيعتمد على الجداول والبيانات والبيانات الوصفية.أتوقع أن أتمكن من إعداد أمثلة من شأنها أن تظهر النتائج في كلا الاتجاهين - المعيار!

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

أود أن أقترح استخدام ميزة EXPLAIN لمعرفة أي التعبيرات هو الأفضل.

أعتقد أن SQL الأفضل سيكون:

حدد * من T1 ، T2 حيث t1.id = t2.id و t1.country = 'US'

ليست هناك حاجة لاستخدام المقارنة الثانية بـ "الولايات المتحدة" إلا إذا كان من الممكن أن تكون الدولة في t2 مختلفة عن t1 لنفس المعرف.

بدلاً من استخدام صلة داخلية ضمنية، سأقوم بضم الجداول بشكل صريح.

نظرًا لأنك تريد أن يكون كل من حقول المعرف وحقول البلد متماثلين، وذكرت أن كلاهما مفهرس (أفترض في نفس الفهرس)، سأقوم بتضمين كلا العمودين في الصلة حتى تتمكن من الاستفادة من البحث عن الفهرس بدلا من المسح.وأخيرًا، أضف جملة Where الخاصة بك.

SELECT *
  FROM t1
  JOIN t2 ON t1.id = t2.id AND t1.country = t2.country
 WHERE t1.country = 'US'

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