سؤال

لدي تطبيق يستخدم NHibernate باعتباره ORM الخاص به وأحيانًا يواجه مشكلات في الأداء بسبب كيفية الوصول إلى البيانات من خلاله.ما نوع الأشياء التي يمكن القيام بها لتحسين أداء NHibernate؟(يُرجى الاقتصار على توصية واحدة لكل إجابة)

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

المحلول

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

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

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

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

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

إحدى المشاكل الصغيرة الصعبة التي واجهناها كانت مع SetParameterList().تسمح لك هذه الوظيفة بتمرير قائمة المعلمات إلى الاستعلام بسهولة.قام NHibernate بتنفيذ ذلك عن طريق إنشاء معلمة واحدة لكل عنصر تم تمريره.وينتج عن هذا خطة استعلام مختلفة لكل عدد من المعلمات.كانت خطط التنفيذ الخاصة بنا يتم تحريرها دائمًا من ذاكرة التخزين المؤقت.بالإضافة إلى ذلك، يمكن أن تؤدي المعلمات المتعددة إلى إبطاء الاستعلام بشكل ملحوظ.لقد قمنا باختراق مخصص لـ NHibernate لإرسال العناصر كقائمة محددة في معلمة واحدة.تم فصل القائمة في SQL Server بواسطة دالة قيمة الجدول التي قام الاختراق بإدراجها تلقائيًا في جملة IN الخاصة بالاستعلام.من الممكن أن تكون هناك ألغام أرضية أخرى مثل هذه اعتمادًا على طلبك.يعد SQL Profiler هو أفضل طريقة للعثور عليهم.

نصائح أخرى

تعد عملية SessionFactory الخاصة بـ NHibernate عملية مكلفة، لذا تتمثل الإستراتيجية الجيدة في إنشاء Singleton الذي يضمن وجود مثيل واحد فقط من SessionFactory في الذاكرة:

   public class NHibernateSessionManager
    {
        private readonly ISessionFactory _sessionFactory;

        public static readonly NHibernateSessionManager Instance = new NHibernateSessionManager();

        private NHibernateSessionManager()
        {
            if (_sessionFactory == null)
            {
                System.Diagnostics.Debug.WriteLine("Factory was null - creating one");
                _sessionFactory = (new Configuration().Configure().BuildSessionFactory());
            }
        }

        public ISession GetSession()
        {
            return _sessionFactory.OpenSession();
        }

        public void Initialize()
        {
            ISession disposeMe = Instance.GetSession();
        }
    }

ثم في Global.Asax Application_Startup، يمكنك تهيئته:

protected void Application_Start()
{
    NHibernateSessionManager.Instance.Initialize();
}

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

لا توجد توصية ولكن أداة لمساعدتك:إن إتش البروفيسور ( http://nhprof.com/ ) يبدو واعدًا، حيث يمكنه تقييم استخدامك لإطار عمل ORM.يمكن أن تكون نقطة انطلاق جيدة لضبط NHibernate.

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

يقوم NHibernate بإنشاء SQL سريع جدًا بمجرد إخراجه من الصندوق.لقد كنت أستخدمه لمدة عام، ولم أضطر بعد إلى كتابة SQL باستخدامه.كل مشاكل أدائي كانت من تطبيع ونقص الفهارس.

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

"توصية واحدة لكل إجابة" فقط؟ثم سأذهب لهذا:

تجنب ربط التكرارات (المنتجات الديكارتية AKA) بسبب الروابط على طول ارتباطين أو أكثر بالتوازي مع العديد من الارتباطات؛استخدم الاستعلامات الفرعية الموجودة أو الاستعلامات المتعددة أو FetchMode "تحديد فرعي" بدلاً من ذلك.

مأخوذ من: نصائح لضبط أداء السبات

هل مسموح لي أن أقتصر إجابتي على خيار واحد فقط؟في هذه الحالة سأختار تنفيذ آلية التخزين المؤقت للمستوى الثاني لـ NHibernate.

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

هدفك هو تحديد الكائنات التي يتم الوصول إليها باستمرار بواسطة التطبيق الخاص بك.ومن بين تلك الإعدادات العامة وما شابه ذلك.

هناك الكثير من المعلومات التي يمكن العثور عليها بخصوص ذاكرة التخزين المؤقت للمستوى الثاني من nhibernate وكيفية تنفيذها.

حظ سعيد :)

التخزين المؤقت، والتخزين المؤقت، والتخزين المؤقت - هل تستخدم التخزين المؤقت للمستوى الأول بشكل صحيح [إغلاق الجلسات قبل الأوان، أو استخدام StatelessSession لتجاوز التخزين المؤقت للمستوى الأول]؟هل تحتاج إلى إعداد ذاكرة تخزين مؤقت بسيطة من المستوى الثاني للقيم التي تتغير بشكل غير متكرر؟هل يمكنك تخزين مجموعات نتائج الاستعلام مؤقتًا لتسريع الاستعلامات التي تتغير بشكل غير متكرر؟

[أيضًا التكوين - هل يمكنك تعيين العناصر على أنها غير قابلة للتغيير؟هل يمكنك إعادة هيكلة الاستعلامات لاستعادة المعلومات التي تحتاجها فقط وتحويلها إلى الكيان الأصلي؟هل سيتمكن باتمان من إيقاف ريدلر قبل أن يصل إلى السد؟...أوه، آسف لقد تم إبعادي.]

يعد التوصيف هو الخطوة الأولى - حتى اختبارات الوحدة البسيطة المحددة بوقت - لمعرفة أين يمكن تحقيق أكبر المكاسب

بالنسبة للتحصيلات، خذ بعين الاعتبار تعيين حجم الدفعة لتقليل عدد كشوفات الحساب المحددة الصادرة - راجع القسم تحسين الأداء للتفاصيل

إذا كنت لا تستخدم التحميل البطيء بالفعل (بشكل مناسب)، فابدأ.يعد جلب المجموعات عندما لا تحتاج إليها مضيعة لكل شيء.

الفصل تحسين الأداء يصف هذا وطرق أخرى لتحسين الأداء.

ماذا قال الكثير من وقت الفراغ.

اقرأ الفصل 19 من الوثائق "تحسين الأداء".
السبات: http://nhibernate.info/doc/nhibernate-reference/performance.html
بيات شتوى: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html

استخدم SQL Profiler (أو ما يعادله لقاعدة البيانات التي تستخدمها) لتحديد موقع الاستعلامات طويلة الأمد.قم بتحسين هذه الاستعلامات باستخدام الفهارس المناسبة.

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

وبالطبع ذاكرة التخزين المؤقت.توجيه OutputCache للصفحات/عناصر التحكم.التخزين المؤقت NHibernate للبيانات.

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