يعد تحسين أداء SQL تحديًا كبيرًا للمبرمجين، لأننا غالبًا ما نواجه هذه المشكلة: عندما نقوم بتطوير مشروع، نشعر أن التجربة الوظيفية لاختباره بأنفسنا جيدة حقًا، ولكن بعد إطلاق المشروع الفعلي، مع الزيادة الهائلة فيما يتعلق بالبيانات، فإن تجربة العملاء للنظام تزداد سوءًا. بالطبع، بالإضافة إلى إطار العمل والتعليمات البرمجية غير المعقولة، السبب الرئيسي هو عدم تحسين SQL، مما تسبب في أن يصبح النظام أبطأ وأبطأ.
ولأنني أعمل في شركة صغيرة، فإنني أفعل كل شيء وأعتقد أنه في بعض الأحيان يكون من الأفضل علاج الأعراض بدلاً من علاج السبب الجذري! هناك العديد من القضايا التي يجب الانتباه إليها:
1. يجب أن يكون تصميم جدول قاعدة البيانات معقولاً، خاصة تصميم المفتاح الأساسي. إذا كانت كمية البيانات في الجدول كبيرة جدًا، فلا ينبغي أن يكون تصميم المفتاح الأساسي ذا معنى، تمامًا مثل ROWID. GUID لـ SQL Server، وUUID للإسبات، وما إلى ذلك. بالطبع، يمكن معالجة بعض جداول قاموس البيانات بمرونة، وليست هناك حاجة إلى اعتبار أنها يجب أن تكون مفاتيح أساسية فعلية. في تصميم المفتاح الأساسي، لا يتم استخدام المفاتيح الأساسية المركبة بشكل عام.
2. الفهرسة المعقولة. يعد الفهرس أداة قوية ووسيلة جيدة لتسريع استعلام البيانات لدينا. ولكن لا تضيف كل حقل. مبدأ الفهرسة يشبه تمامًا جدول محتويات الكتاب، إذا كان جدول محتويات كتابك يحمل نفس الاسم تقريبًا، فيمكنك تخيل ما يلي: ما مدى سرعة العثور على المحتوى المحدد وفقًا لجدول المحتويات ؟ ليس من الضروري أن يكون الفهرس فريدًا، ولكن لا ينبغي أن يحتوي على عدد كبير جدًا من السجلات المتطابقة. علاوة على ذلك، إذا تمت إضافة المزيد من الفهارس، ستزيد مساحة جدول TEMP. عند تصدير الجدول واستيراده إلى قاعدة بيانات أخرى، ستعمل الفهارس أيضًا على تقليل كفاءة الاستيراد. في هذا الوقت، ستجد أيضًا أن مساحة الجدول UNDOTBS01 كبيرة بشكل غير طبيعي. ولذلك فإن المؤشر سلاح ذو حدين ويجب تطبيقه بشكل معقول.
3. لقد رأيت بعض المقالات الاحترافية جدًا حول تحسين SQL على الإنترنت، لكنني أشعر أنني لم أتمكن من استخدامها في مشروعي. وبدلاً من ذلك، واصلت التجربة واكتشاف بعض المبادئ الأساسية خلال المشروع. أنا شخصياً أعتقد أن هناك مبدأ واحدًا فقط لتحسين SQL، وهو تضييق نطاق الاستعلام قدر الإمكان، وهذا سيؤدي بالتأكيد إلى تحسين الكفاءة، ويمكن لشركة Oracle نفسها تحسين SQL الذي نكتبه، لذا ما يتعين علينا فعله هو ذلك تضييق نطاق الاستعلام قدر الإمكان. وبالحديث عن هذا، أعتقد أن الجميع سيعتقد بالتأكيد أن الفهرسة هي أداة قوية لتحسين سرعة الاستعلام، وهي في الواقع مجرد وسيلة، وهي تنبع أيضًا من مبدأ تضييق نطاق الاستعلام .
معظم SQL التي تحتاج إلى التحسين هي استعلامات ربط الجداول المتعددة، وتتضمن عمليات ربط الجداول المتعددة أيضًا روابط أفقية وروابط رأسية. يعني الاتصال الأفقي بشكل عام أن بنية الحقل لجدولين هي نفسها بشكل أساسي، ويجب تغيير بعض سجلات البيانات من جدول واحد إلى بعض سجلات جدول آخر، أي الصفوف + الصفوف. الاتصال العمودي يعني أننا نأخذ بعض الحقول للاستعلام عنها من الجدول أ، وبعض الحقول للاستعلام عنها من الجدول ب، ثم نربط الجداول المأخوذة من الجدولين أ و ب رأسيًا باستخدام الجزء المشترك، أي الأعمدة + الأعمدة.
بيان الصلة الأفقية: حدد a.column1,a.column2 من tableA اتحاد الكل حدد b.column1,b.column2 من tableB b
لاحظ أنه عند الاتصال أفقيًا، يجب أن يكون عدد الأعمدة هو نفسه، ويجب أن تكون أنواع بيانات أعمدة الحقول المقابلة هي نفسها. في الواقع، يمكنك التفكير في الجداول التي سيتم توحيدها كنسخة واحدة من الأخرى، تمامًا كما هي. قد يتساءل شخص ما، إذا كانت الأعمدة التي أرغب في دمجها تحتوي على أعمدة مختلفة، أو لا يوجد عمود على الإطلاق، فيمكنك استخدام الطريقة التالية
حدد d.dname،d.loc من dept1 d union all حدد '' dname، e.loc من dept e، انظر إلى "'' dname"، يمكننا أن نجد بسهولة أنه يمكنك العثور على بديل، استخدم سلسلة فارغة بدلاً من ذلك هناك ليست هناك حقول، لذا يمكن دمجها.
بيان الصلة العمودية: حدد a.column1,a.column2 من tableA، صلة خارجية كاملة حدد b.column3,b.column4 من tableB b على a.aid=b.bid حيث...، هذا تنسيق صلة خارجية كاملة. هذه السرعة سريعة جدًا بالفعل، لكن قد لا يعجبك الاستعلام، نظرًا لوجود بعض صفوف النتائج التي قد لا ترغب في رؤيتها على الإطلاق. في الظروف العادية، نستخدم الصلة الخارجية اليسرى والوصلة الخارجية اليمنى أكثر. الفرق بين الاثنين هو أن الصلة الخارجية اليسرى تعتمد بشكل أساسي على الجدول المقابل لحقل الربط على اليسار، والوصلة الخارجية اليمنى هي العكس تمامًا. بالطبع يمكنك أيضًا استخدام الانضمام الأيسر والانضمام الأيمن. أثناء الاستخدام، ما زلت أجد أن الاتصالات الخارجية أسرع نسبيًا.
لتسريع كفاءة استعلامات الاتصال العمودي، الطريقة هي تداخل الاستعلامات. وفيما يلي مثال فعلي من المشروع:
حدد c.customerid، c.receivedmoney، c.tollcollector، c.receiveddate، c.yearmonth، c.receivedlatefee،
c.receivedfee،c.receivedappend،c.jmman،c.jmmoney،c.name،d.chargeint من
(اختر أ.معرف العميل،أ.المال المستلم،أ.مجمع الرسوم،أ.تاريخ الاستلام،أ.الشهر،أ.رسوم متأخرة،
a.receivedfee،a.receivedappend،a.jmman،a.jmmoney،b.name from
(اختر rf.customerid،rf.receivedmoney،rf.tollcollector،rf.receiveddate،rf.yearmonth،rf.receivedlatefee،
rf.receivedfee,rf.receivedappend,rf.jmman,rf.jmmoney من sf_receivedfee rf حيث
rf.electriccompanyid='1000000001' وrf.dealsign=0 وrf.yearmonth in(200811,200901,200903,200804,200805,200806,200807)
وrf.customerid=1000052545) صلة خارجية يسرى (حدد xe.employeeid,xe.name من xt_employee xe) b على a.tollcollector=b.employeeid)
c الصلة الخارجية اليسرى (حدد cp.chargeint,cp.customerid من sf_chargeprotocol cp حيث cp.customerid=1000052545) d
على c.customerid=d.customerid
يمكنك أن ترى أنه في هذا المثال، نقوم أولاً بتصفية السجلات التي نحتاجها من كل جدول باستخدام نفس الشروط تقريبًا، ثم نقوم بدمج السجلات في الاستخدام الفعلي، ووجدت أن هذا أسرع بنحو 60 مرة من استعلام الارتباط المباشر. على الرغم من أنه قبيح وصعب القراءة، إلا أنه يحل مشكلة أداء SQL. المبدأ الذي يستخدمه هو تضييق النطاق أولاً، ثم إجراء استعلام اتصال، إذا قمنا بالاتصال ثم التصفية، فهذا يعادل دمج جدولين، ثم جلب البيانات بناءً على الظروف.