سؤال

أقوم بتشغيل استعلام مقابل جدول في قاعدة بيانات postgresql.قاعدة البيانات موجودة على جهاز بعيد.يحتوي الجدول على حوالي 30 جدولًا فرعيًا باستخدام postgresql القدرة على التقسيم.

سيُرجع الاستعلام مجموعة نتائج كبيرة، حوالي 1.8 مليون صف.

في الكود الخاص بي أستخدم طريقة دعم Spring jdbc JdbcTemplate.query, ، ولكن بلدي RowCallbackHandler لا يتم استدعاؤه.

أفضل تخميني هو أن برنامج تشغيل postgresql jdbc (أستخدم الإصدار 8.3-603.jdbc4) يقوم بتجميع النتيجة في الذاكرة قبل استدعاء الكود الخاص بي.اعتقدت أن تكوين حجم الجلب يمكن السيطرة على هذا، ولكن حاولت ذلك ولم يتغير شيء.لقد فعلت هذا كدليل Postgresql موصى به.

كان هذا الاستعلام يعمل بشكل جيد عندما استخدمت Oracle XE.لكنني أحاول الانتقال إلى postgresql بسبب ميزة التقسيم غير المتوفرة في Oracle XE.

بيئتي:

  • بوستجريس 8.3
  • ويندوز سيرفر 2008 إنتربرايز 64 بت
  • جي آر إي 1.6 64 بت
  • الربيع 2.5.6
  • برنامج تشغيل Postgresql JDBC 8.3-603
هل كانت مفيدة؟

المحلول

لكي تتمكن من استخدام المؤشر لاسترداد البيانات، يجب عليك تعيين نوع ResultSet لـ ResultSet.TYPE_FORWARD_ONLY (الافتراضي) والالتزام التلقائي بالقيمة false بالإضافة إلى تحديد حجم الجلب.تمت الإشارة إلى ذلك في المستند الذي قمت بالارتباط به ولكنك لم تذكر صراحةً أنك قمت بهذه الخطوات.

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

نصائح أخرى

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

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

إذا لم يكن عميلاً، وتم تدليك النتائج بطريقة ما، فإنني أوصي بالسماح لقاعدة البيانات بمعالجة كل تلك الصفوف وإرجاع النتيجة ببساطة.ليس من المنطقي إرجاع 1.8 مليون صف فقط لإجراء عملية حسابية على الطبقة الوسطى.

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

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

أوصي بإعادة توجيه نفسك - ابدأ بالتفكير في الأمر كحل لإعداد التقارير.

عملت الخاصية fetchSize كما هو موضح في دليل بوستجرس.

كان خطئي أنني كنت أقوم بتعيين الالتزام التلقائي = خطأ لاتصال من تجمع اتصال لم يكن الاتصال الذي يستخدمه البيان المعد.

شكرا لكل الردود.

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

أضفت هذا: @Transactional(readOnly = true)

هتافات.

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