مقدمة
هذه المقالة موجهة لمطوري قواعد البيانات Database Developers بشكل عام ومطوري قواعد البيانات في مشروع أروى ARWA بشكل خاص.
سيتم في هذه المقالة دراسة الحلول المقترحة للمسألة المطروحة في المقالة السابقة، وذلك من خلال عرض نتائج الأداء للحلول المقبولة، ومن ثم مناقشة تلك النتائج، وفي الختام عرض للأفكار المقترحة.
الحلول المقترحة
إن الحلول المقترحة لحل المسألة تنوعت في أفكارها ونتائجها، وهو ما أغنى المسألة وأوجد مجالاً للنقاش والتعلم، وهو الهدف الأساسي لهذه المقالات.
عدد الحلول المقترحة هو 10 حلول (8 حلول مرسلة مع حلين مقترحين من قبلي)وهي (مرتبة حسب تاريخ الإرسال):
دراسة الحلول المقبولة
بعض الحلول (ونتيجة لاستخدام توابع معرّفة مسبقاً) لم تعطي نتائج صحيحة كلياً، ولكن تم اعتبارها مقبولة لأن الخطأ لا يتبع للحل أساساً.
أما في ما يتعلق بالحل المقترح من قبل السيد هاني السائح فهو لم يعطي نتائج صحيحة لذلك لم يعتبر حلاً مقبولاً لدراسة أداءه ولكن سنناقش الفكرة التي بعرضها عند مناقشة الحلول.
ملاحظة:لم تأخذ أغلبية الحلول (باستثناء حل السيد أحمد غانم رقم 1) بعين الاعتبار أن القيود التي تم ترحيلها (IsPosted <> 0) هي فقط القيود التي تدخل في حساب المدين والدائن، وبالرغم من تأثير هذا الشرط على الأداء (يتطلب دمج Join مع الجدول ce000) فإن الحلول التي لم تحققه تم اعتبارها مقبولة كما هي.
تم دراسة الحلول المقبولة على جهازين مختلفين وباستخدام قاعدتي بيانات مختلفتين.
الجهاز الأول هو جهاز عادي بمواصفات متوسطة، أما الجهاز الثاني فهو مخدم بمواصفات جيدة.
قاعدة البيانات الأولى هي قاعدة بيانات متوسطة الحجم، أما قاعدة البيانات الثانية فهي قاعدة بيانات جيدة الحجم.
سيتم عرض النتائج على أربع جداول كل جدول يمثل حالة دراسة، ووفق المعايير التالية:
- الزمن الكلي الذي استغرقه تنفيذ الاستعلام بالميلي ثانية.
- زمن المعالجات CPU Time الذي استغرقه تنفيذ الاستعلام بالميلي ثانية، وقد يكون في بعض الأحيان أكبرمن الزمن الكلي وذلك نتيجة لأن خطة التنفيذ Execution Plan المستخدمة هي خطة تنفيذ تفرعية.
- عدد القراءات المنطقية Logical Reads التي تطلبها تنفيذ الاستعلام، وهي تمثل عدد القراءات من الذاكرة المخبئية Cache و لا يدخل ضمنها القراءات من الملفات الفيزيائية، هي تعد من أهم المعايير لدراسة أداء الاستعلامات، ولكنها ليست كافية لوحدها.
- عدد الكتابات Writes التي تطلبها تنفيذ الاستعلام، وهي تتضمن الكتابة على TempDB نتيجة استخدام جداول مؤقتة أو نتيجة خطة التنفيذ التي تشير إلى تخزين النتائج المؤقتة لتحسين أداء الاستعلامات.
ملاحظة:سترتب النتائج وفق معيار الزمن الكلي.
النتائج
جهاز عادي وقاعدة بيانات متوسطة الحجم
الترتيب | الحل المقترح | الزمن الكلي | زمن المعالجات | عدد القراءات المنطقية | عدد الكتابات |
1 | محمد الباشا | 455 | 656 | 51581 | 90 |
2 | محمد الباشا2 | 2765 | 2766 | 258062 | 37 |
3 | معاوية الرفاعي | 3656 | 3641 | 403184 | 14 |
4 | وسيم العش2 | 3812 | 3782 | 552288 | 25 |
5 | أحمد غانم2 | 10640 | 10625 | 511814 | 55 |
6 | وسيم العش1 | 13229 | 13141 | 691864 | 37 |
7 | أحمد غانم1 | 21772 | 21688 | 955032 | 61 |
8 | رضوان نصري | 22591 | 21828 | 3167064 | 100 |
9 | محمد القجة | 175715 | 173782 | 173782 | 231 |
جهاز عادي وقاعدة بيانات جيدة الحجم
الترتيب | الحل المقترح | الزمن الكلي | زمن المعالجات | عدد القراءات المنطقية | عدد الكتابات |
1 | محمد الباشا | 19750 | 21141 | 467288 | 146 |
2 | محمد الباشا2 | 24921 | 19969 | 687798 | 55 |
3 | وسيم العش2 | 52921 | 47718 | 8687475 | 55 |
4 | أحمد غانم2 | 142612 | 131422 | 10315913 | 61 |
5 | رضوان نصري | 160318 | 152437 | 13706039 | 291 |
6 | وسيم العش1 | 172470 | 159953 | 12810629 | 392 |
7 | معاوية الرفاعي | 259546 | 255641 | 19103395 | 60 |
8 | محمد القجة | 401970 | 387609 | 11264301 | 672 |
9 | أحمد غانم1 | 413724 | 413047 | 30062186 | 380 |
جهاز جيد وقاعدة بيانات متوسطة الحجم
الترتيب | الحل المقترح | الزمن الكلي | زمن المعالجات | عدد القراءات المنطقية | عدد الكتابات |
1 | محمد الباشا | 296 | 500 | 51205 | 98 |
2 | محمد الباشا2 | 1890 | 1859 | 257820 | 44 |
3 | وسيم العش2 | 2473 | 2437 | 551978 | 60 |
4 | معاوية الرفاعي | 2561 | 2500 | 402876 | 44 |
5 | أحمد غانم2 | 2778 | 2734 | 511446 | 60 |
6 | وسيم العش1 | 3424 | 3343 | 691239 | 88 |
7 | أحمد غانم1 | 5446 | 5297 | 954377 | 88 |
8 | رضوان نصري | 7778 | 7688 | 3165891 | 104 |
9 | محمد القجة | 32843 | 32469 | 4146255 | 306 |
جهاز جيد وقاعدة بيانات جيدة الحجم
الترتيب | الحل المقترح | الزمن الكلي | زمن المعالجات | عدد القراءات المنطقية | عدد الكتابات |
1 | محمد الباشا | 7132 | 12969 | 436137 | 131 |
2 | محمد الباشا2 | 11967 | 10969 | 684210 | 155 |
3 | وسيم العش2 | 23224 | 23031 | 8682505 | 47 |
4 | أحمد غانم2 | 33079 | 29594 | 10311155 | 52 |
5 | وسيم العش1 | 40690 | 35594 | 12806518 | 83 |
6 | رضوان نصري | 46301 | 41875 | 13726787 | 142 |
7 | معاوية الرفاعي | 70514 | 70125 | 19098823 | 54 |
8 | أحمد غانم1 | 98805 | 97937 | 30062481 | 89 |
9 | محمد القجة | 105268 | 104422 | 11253183 | 662 |
مناقشة النتائج
نلاحظ من قراءة النتائج أن لعدد القراءات المنطقية تأثيراً واضحاً على أداء الاستعلام، ولكنه وحده ليس كافياً فهنالك عوامل أخرى تؤثر أيضاُ ومنها القراءات الفيزيائية من الملفات.
كما أننا نلاحظ أثر استخدام التابع fnCurrency_fix وهو تابع إحادي القيمة Scalar Value Function على الأداء عند ازدياد حجم البيانات، ولتوضيح ذلك لنقارن أداء حل السيد معاوية الرفاعي وحل السيد وسيم العش رقم 2 (الذي يستخدم تابع جدولي القيمة Table Value Function)، فالأول كان أسرع عندما كان حجم قاعدة البيانات متوسطاً وكان الحاسب المستخدم حاسب عادي، بينما كان حل السيد وسيم العش رقم 2 أسرع في باقي الحالات. وطبعاً تمايزت الحلول المقترحة والتي تستخدم التابع fnCurrency_fix في أدائها وذلك تبعاً للموقع الذي تم استخدام هذا التابع فيه مما منحها خصائص متمايزة.
أما في ما يخص حل السيد أحمد غانم رقم 1 فهو الحل الأبسط والمباشر لهذه المسألة ولكنه من أبطأ الحلول لأنه أضاف طبقة أخرى من التوابع أحادية القيمة فوق باقي الحلول فهو يستخدم التابعين أحادي القيمة fnAccount_getCredit وfnAccount_getDebit اللذان يستخدمان التابع fnCurrency_fix بدورهما، لكنه الحل الوحيد (باستثناء الحلين المقترحين من قبلي) الذي أخذ بالاعتبار القيود المرحلة فقط.
أما في ما يخص الحلول المقترحة من قبل السادة رضوان نصري وأحمد غانم (الحل رقم2) ووسيم العش ومعاوية الرفاعي فهي تتشارك منهجية حل مشتركة (مقترحة أساساً من قبل السيد رضوان نصري) وهي تبين منهجية تفكير موجهة باستخدام التوابع جدولية القيمة بدلاُ ن التوابع أحادية القيمة، وهي منهجية سليمة ولها أثرها الواضح على الأداء من حيث التعامل مع البيانات كمجموعات وليس كأسطر مفردة، ومن حيث تكامل أجزاء الاستعلام مع بعضعا كوحدة واحدة يمكن أمثلتها من قبل محرك قواعد البيانات، ولكن جزئية استبدال التابع fnCurrency_fix بتابع آخر هي فكرة مميزة طرحها السيد وسيم العش في حله رقم 2 وكان لها الأثر الكبير على الأداء نتيجة ارتباط هذا التابع بجدول القيود وهو الجدول الأكبر بين كل الجداول المستخدمة في الاستعلام، ولكن آلية كتابة هذا التابع و كيفية استخدامه تحتاج لبعض التصحيح والأمثلة.
أما في ما يخص حل السيد محمد القجة فهو ذو فكرة مميزة (سنناقشه في الفقة اللاحقة) ولكن أداءه منخفص نتيجة المنجية الإجراءاتية (لم أجد كلمة أفضل) بدلاً من الاستفادة من المزايا الموجودة في SQL Server، بالإضافة لآلية كتابة الاستعلامات التي يمكن أن تكتب بشكل أكثر أمثلةً.
أما في ما يخص حلولي للمسألة فإنها قائمة على شيء مشابه للأفكار المقترحة من قبل الآخرين، ولتكون كمثال عملي لما أشرت إليه في هذه الفقرة.
عرض للأفكار المقترحة
سأعدد الأفكار المقترحة من قبل المشاركين في حل المسألة وهي:
- استخدام التوابع جدولية القيمة ودمجها ضمن الاستعلام كبنية واحدة، وقد تم اقتراحها أساساً من قبل السيد رضوان نصري.
- استبدال التابع fnCurrency_fix أحادي القيمة بتابع آخر جدولي القيمة، وقد تم اقتراحها أساساً من قبل السيد وسيم العش.
- استبدال التابع fnGetAccountsList بتابع أو استعلام آخر، وقد تم اقتراحها أساساً من قبل السيد وسيم العش ولكنه لم يقدم حلاً صحيحاً، ولكن حلي رقم 1 يستبدل هذا التابع باستعلام مستخدماً الـ CTE.
- معالجة شجرة الحساب من الأوراق صعوداً، وقد تم اقتراحها أساساً من قبل السيد محمد القجة، وهي مشابهة للآلية المستخدمة في حلي رقم 1 ولكن مع الفرق بأني ولدت أسلاف الحسابات انطلاقاً من كامل جدول الحسابات ولم أحسبها من أجل كل حساب على حدا.
- تجميع ارصدة الحسابات جمعاً جبرياً وهو الحل المقترح من قبل السيد هاني السائح والذي إن اكتمل بشكل صحيح قد يعطينا وجهة نظر مختلفة لحل المسألة.
الخاتمة
كنت أتمنى أن يكون عدد المشاركات أكبر، وأن يشاركنا كل بفكرته حتى لو كانت من وجهة نظره ليست أمثلية، فالهدف الأساسي لهذه المقالات هو المشاركة وتبادل الأفكار، والتي من خلالها يمكن الوصول لحلول أمثلية للمسائل التي تواجهنا حقيقةً، ولكن ما يشجع هو أن المشاركين أفادونا بأفكار جيدة وبناءة.
اضف تعليقا
يجب logged in لكي تضيف ردا.