النفقات العامة للتحدد MySQL - أفضل لاستخدام واحد، أو الكثير في التسلسل

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

سؤال

هل هناك فرق أداء ملموس بين وجود واحد SELECT foo, bar, FROM users الاستعلام الذي يعود 500 صفوف، و 500 SELECT foo, bar, FROM users WHERE id = x استفسارات قادمة في وقت واحد؟

في تطبيق PHP، أكتب، أحاول الاختيار بين قسم الكتابة واضحة، مقروء من التعليمات البرمجية التي من شأنها أن تنتج حوالي 500 عبارة؛ أو كتابة ذلك بطريقة غامضة ومعقدة من شأنها استخدام واحد فقط حدد هذا يعود 500 صفوف.

أفضل أن أستخدم الطريقة التي تستخدم رمز واضح وصقي، لكنني أشعر بالقلق من أن النظام العلوي لكل من المحددات سوف يسبب مشاكل في الأداء.

معلومات أساسية، في حالة صلة: 1) هذه وحدة دروبال، مشفرة في PHP 2) تحصل الجداول المعنية على عدد قليل جدا من الإدراجات والتحديثات، ونادرا ما تكون مغلقة 3) لا يمكن الوصول إلى SQL لأسباب غير ذات صلة سؤال

شكرًا!

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

المحلول

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

نصائح أخرى

لا أشعر بالقلق بشأن الاتصال النفقات العامة لاستعلامات MySQL أكثر من اللازم، خاصة إذا كنت لا تغلق الاتصال بين كل استعلام. ضع في اعتبارك أنه إذا قام الاستعلام بإنشاء جدول مؤقت، فقد أمضيت بالفعل المزيد من الوقت في الاستعلام من النفقات العامة التي استغرقها الاستعلام.

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

أقترح هذا:

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

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

3) مشاركة النتائج مع فريقك.

الاستعلامات المعقدة أقل عرضة لضرب ذاكرة التخزين المؤقت لاستعلام MySQL، وإذا كانت كبيرة بما يكفي، فلا تخبئها. (تريد حفظ ذاكرة التخزين المؤقت لاستعلام MySQL للاستعلامات المتأثرة بشكل متكرر.) أيضا، استعلام حيث يتسبب في مسح الفهرس كذلك. (x! = y، x> y، x <y). استعلامات مثل SELECT foo, bar FROM users WHERE foo != 'g' and mumble < '360' ينتهي في القيام بمسح. (قد تكون تكلفة الاستعلام العلوية ضئيلة في هذه الحالة.)

غالبا ما يمكن أن تكتمل الاستعلامات الصغيرة دون إنشاء جداول مؤقتة فقط من خلال الحصول على جميع القيم من الفهرس، طالما أن الحقول التي تختارها وتسدد المفهرسة. لذلك أداء الاستعلام ل SELECT foo, bar FROM users WHERE id = x هو رائع حقا (esp إذا الأعمدة foo و bar هي مفهرسة مثل، ويعرف أيضا باسم alter table users add index ix_a ( foo, bar );.)

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

يبدو أنك تعرف ما هو 500 id القيم هي، فلماذا لا تفعل شيئا مثل هذا:

// Assuming you have already validated that this array contains only integers
// so there is not risk of SQl injection

$ids = join(',' $arrayOfIds);

$sql = "SELECT `foo`, `bar` FROM `users` WHERE `id` IN ($ids)";
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top