ما هو الأمثل؟الاتحاد مقابل أين يوجد (str1، str2، str3)

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

  •  09-06-2019
  •  | 
  •  

سؤال

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

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

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)

أو

SELECT email FROM tClient WHERE timezoneID = 1
    UNION ALL SELECT email FROM tClient WHERE timezoneID = 4
    UNION ALL SELECT email FROM tCLIENT WHERE timezoneID = 9

يحرر: timezoneID هو مفتاح خارجي لـ tTimezone، وهو جدول يحتوي على timezoneID للمفتاح الأساسي وحقل varchar(20) timezoneName. وأيضا ذهبت مع WHERE IN لأنني لم أشعر برغبة في فتح المحلل.

تحرير 2: يعالج الاستعلام 200 ألف صف في أقل من 100 مللي ثانية، لذا فقد انتهيت عند هذه النقطة.

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

المحلول

يا!هذه الاستعلامات ليست متكافئة.

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

استخدم UNION ALL دائمًا، إلا إذا كنت تعرف سبب رغبتك في استخدام UNION.

إذا لم تكن متأكدا ما هو الفرق انظر هذا هذا سؤال.

ملحوظة:هذا الصراخ ينتمي إلى إصدار سابق من السؤال.

نصائح أخرى

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

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

تخميني الأول سيكون ذلك

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)
سيكون أسرع لأنه يتطلب فحصًا واحدًا فقط للجدول للعثور على النتائج، لكنني أقترح التحقق من خطة التنفيذ لكلا الاستعلامين.

ليس لدي محلل استعلام MS SQL في متناول اليد للتحقق فعليًا من فرضيتي، ولكن أعتقد أن متغير WHERE IN سيكون أسرع لأنه مع خادم UNION سيتعين عليه إجراء 3 عمليات فحص للجدول بينما مع WHERE IN سيحتاج إلى عملية واحدة فقط.إذا كان لديك محلل الاستعلام، فتحقق من خطط التنفيذ لكلا الاستعلامين.

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

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

في كتاب "ضبط أداء SQL"، وجد المؤلفون أن استعلامات UNION كانت أبطأ في جميع أنظمة إدارة قواعد البيانات السبعة التي اختبروها (SQL Server 2000، وSybase ASE 12.5، وOracle 9i، وDB2، وما إلى ذلك): http://books.google.com/books?id=3H9CC54qYeEC&pg=PA32&vq=UNION&dq=sql+performance+tuning&source=gbs_search_s&sig=ACfU3U18uYZWYVHxr2I3uUj8kmPz9RpmiA#PPA33,M1

ربما يكون نظام إدارة قواعد البيانات (DBMS) الأحدث قد حسّن هذا الاختلاف، لكن هذا أمر مشكوك فيه.كما أن طريقة UNION أطول بكثير وأكثر صعوبة في الصيانة (ماذا لو كنت تريد طريقة ثالثة؟) مقابل طريقة UNION.في.

ما لم يكن لديك سبب وجيه لاستخدام UNION، فالتزم بأسلوب OR/IN.

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

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