it-swarm.asia

ما هو أسرع ، استعلام واحد كبير أو العديد من الاستعلامات الصغيرة؟

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

لذا ، هل سيكون من الأسرع إجراء تحديدات بسيطة ، ثم "الانضمام" إليها في رمز النظام؟

يمكن أن يكون النظام php ، Java ، asp ، أي لغة تتصل بقاعدة البيانات.

لذا فإن السؤال هو ، ما هو أسرع من جانب الخادم (php ، Java ، asp ، Ruby ، ​​python ...) إلى قاعدة البيانات تشغيل استعلام واحد يحصل على كل ما نحتاجه أو الانتقال من جانب الخادم إلى قاعدة البيانات وتشغيل الاستعلام الذي يحصل فقط على الأعمدة من جدول واحد في ذلك الوقت؟

76
sudo.ie

ما يعالج سؤالك هو موضوع الانضمام.

حسب الصفحة 209 من الكتاب

High Performance MySQL

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

SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id = tag.id
JOIN post ON tag_post.post_id = post.id
WHERE tag.tag = 'mysql';

يمكنك تشغيل هذه الاستعلامات:

SELECT * FROM tag WHERE tag = 'mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);

لماذا تفعل هذا على الأرض؟ يبدو الأمر مسرفًا للوهلة الأولى ، لأنك قمت بزيادة عدد الاستعلامات دون الحصول على أي شيء في المقابل. ومع ذلك ، يمكن أن تعطي إعادة الهيكلة هذه ميزات أداء كبيرة:

  • يمكن أن يكون التخزين المؤقت أكثر كفاءة. تخزن العديد من التطبيقات "كائنات" يتم تعيينها مباشرةً إلى الجداول. في هذا المثال ، إذا كان الكائن الذي يحمل العلامة mysql قد تم تخزينه مؤقتًا بالفعل ، فسيتخطى التطبيق الاستعلام الأول. إذا وجدت مشاركات بمعرف 123 أو 567 أو 908 في ذاكرة التخزين المؤقت ، فيمكنك إزالتها من قائمة IN(). قد تستفيد ذاكرة التخزين المؤقت للاستعلام أيضًا من هذه الإستراتيجية. إذا تغير جدول واحد فقط بشكل متكرر ، يمكن أن يؤدي تحليل صلة إلى تقليل عدد عمليات إلغاء صلاحية ذاكرة التخزين المؤقت.
  • يمكن أن يؤدي تنفيذ الاستعلامات بشكل فردي أحيانًا إلى تقليل التنافس على التأمين
  • يؤدي الانضمام إلى التطبيق إلى تسهيل قياس قاعدة البيانات عن طريق وضع الجداول على خوادم مختلفة.
  • يمكن أن تكون الاستعلامات نفسها أكثر كفاءة. في هذا المثال ، فإن استخدام قائمة IN() بدلاً من صلة تتيح لـ MySQL فرز معرفات الصف واسترداد الصفوف بشكل أفضل مما قد يكون ممكنًا مع صلة.
  • يمكنك تقليل عمليات الوصول إلى الصف الزائدة. يعني إجراء عملية ربط في التطبيق استرداد كل صف مرة واحدة فقط. ، في حين أن عملية الانضمام في الاستعلام هي في الأساس عملية تطبيع قد تصل بشكل متكرر إلى نفس البيانات. وللسبب نفسه ، قد تؤدي إعادة الهيكلة هذه أيضًا إلى تقليل إجمالي حركة مرور الشبكة واستخدام الذاكرة.
  • إلى حد ما ، يمكنك عرض هذه التقنية على أنها تنفيذ صلة تجزئة يدويًا بدلاً من خوارزمية الحلقات المتداخلة التي تستخدمها MySQL لتنفيذ صلة. قد تكون صلة التجزئة أكثر كفاءة.

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

الملاحظة

تعجبني النقطة الأولى لأن InnoDB يكون صغيرًا بعض الشيء عندما يقوم بمراجعة ذاكرة التخزين المؤقت للاستعلام.

أما بالنسبة للنقطة الأخيرة ، فقد كتبت منشورًا في 11 مارس 2013 ( هل هناك فرق في التنفيذ بين شرط JOIN وشرط WHERE؟ ) الذي يصف خوارزمية الحلقة المتداخلة. بعد قراءتها ، سترى كيف يمكن أن يكون تحليل التحلل جيدًا.

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

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

بالنسبة لهؤلاء المطورين الراغبين ...

جربها !!!

73
RolandoMySQLDBA

في Postgres (وربما أي RDBMS إلى حد مماثل ، MySQL إلى حد أقل) ، استعلامات أقل تقريبًا دائمًا كثير أسرع.

إن النفقات العامة للتحليل والتخطيط للاستعلامات المتعددة هي بالفعل أكثر من أي مكاسب محتملة في معظم الحالات.

ناهيك عن عمل إضافي يجب القيام به في العميل ، والجمع بين النتائج ، والتي عادة ما تكون much أبطأ في ذلك. يتخصص RDBMS في هذا النوع من المهام والعمليات على أنواع البيانات الأصلية. لا إرسال إلى text والعودة للحصول على نتائج وسيطة أو التحول إلى أنواع أصلية من العميل ، مما قد يؤدي إلى نتائج أقل صحة (أو غير صحيحة!). فكر في أرقام الفاصلة العائمة ...

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

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

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

سؤال ذو صلة على SO:

قد تكون هناك نقطة تحول لـ كبير جدًا ، الاستعلامات الطويلة لأن المعاملات تجمع أقفال على صفوف DB في الطريق. قد تحتوي الاستعلامات الكبيرة جدًا على العديد من الأقفال لفترة طويلة من الزمن والتي قد تسبب احتكاكًا مع استعلامات متزامنة.

29
Erwin Brandstetter