أي حل لعدم كفاءة Oracle TNS (العديد من المستديرة ، الكمون) من تطبيق Java؟

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

  •  28-09-2019
  •  | 
  •  

سؤال

كنت أنظر إلى استعلام SQL بطيء جدًا (نشأ من تطبيق Java باستخدام Hibernate تم نشره في JBOSS 5.1). عاد هذا الاستعلام المعين حوالي 10 آلاف سجلات ولكنه لا يزال يستغرق 40s أو أكثر.

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

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

إذا قمت بتشغيل نفس الاستعلام من مطور SQL Oracle ، فأنا لا أرى هذا النمط. يكمل الاستعلام في حوالي 1/10 من الوقت ، دون الآلاف من الرحلات المستديرة.

نسخة مختصرة: يبدو أن بروتوكول Oracle's Wire (TNS) يمرر البيانات في حزمة TNS واحدة لكل صف نتائج الاستعلام ويتطلب من كل حزمة الاعتراف بها من قبل العميل قبل أن يرسل الخادم الحزمة التالية.

لقد وجدت بعض المعلومات حول هذا [هنا] [1] (قم بالتمرير لأسفل حتى القسم الموجود في "معلمات SDU و TDU في ملف tnsnames.ora").

وبالتالي سؤالي: هل من الممكن التحكم في سلوك برنامج تشغيل Oracle (أنا أستخدم 10.2.0.4.0) وبالتالي فإن بروتوكول TNS أكثر كفاءة؟ مرة أخرى ، هذا تطبيق J2EE قياسي للغاية تم نشره في JBOSS.

شكرًا جزيلاً!

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

المحلول

ضبط SDU و TDU المعلمات في tnsnames.ora و leader.ora

لتعيين حجم الدُفعة على 100 للاحصاء الحالي.

  ((OracleStatement)stmt).setRowPrefetch (100);

ملحوظة:

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

(من دليل مطور Oracle Database JDBC ومرجعه )

خصائص الاتصال المتاحة هنا.

إلقاء نظرة أيضًا على Oracle UCP جدا.

نصائح أخرى

حاول زيادة حجم الجلب لكائن Satement الخاص بك.

أعتقد أن الافتراضي هو 10 ، لذلك قد تحاول البدء بـ 100.

Statement stmt = connection.createStatement();
stmt.setFetchSize(100);
ResultSet rs = stmt.executeQuery("SELECT ...");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top