كيفية تحسين الإستعلامات إلى قاعدة البيانات على ووردبريس

كيفية تحسين الإستعلامات إلى قاعدة البيانات على ووردبريس



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

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

تحسين الإستعلامات على قاعدة البيانات

في ووردبريس لدينا عدة وسائل للتعامل مع قواعد البيانات لكن في غالب الحالات نستخدم WP_Query.

اقرأ أيضا: طريقة عرض المقالات اﻷكثر تعليقا في ووردبريس دون إضافة

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

دائما عند قيامك باستعلام عن طريق WP_Query خد بعين الإعتبار البرمترات التالية:

$args = [ 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'posts_per_page' => 5 ]; $the_query = new WP_Query( $args );
Code language: PHP (php)

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

اقرأ أيضا: روابط nofollow في تصنيفات أو وسوم معينة

update_post_term_cache  هذا البارمتر اعطيه القيمة false لكي لا يتم تحديث التخزين المؤقت للتصنيفات و الوسوم و التصنيفات المخصصة، هكذا توفر عليك استعلام آخر ( فقط استخدمه إذا كنت لا تحتاج ترتيب المواضيع حسب التصنيف (taxonomy)!).

update_post_term_cache  هو نفس ما ذكرناه سابقا لكن هذه المرة يتعلق بالتخزين المؤقت الخاص بالخصائص الإضافية ( post meta)، ففي حالة عدم إدراج خصائص إضافية في الإستعلام يمكنك إعطائها القيمة false.

posts_per_page  هذا البرامتر يمكن من خلاله تحديد عدد المواضيع التي سيتم جلبها من قاعدة البيانات، ولجب كل المواضيع هناك من يضع 1- وهذا قد لا يكون مناسب إذا كان الموقع الذي تعمل عليه يتوفر على آلاف المقالات فمن الأفضل تحديد عدد المقالات الواجب جلبها لتخفيف العبء على الخادم، على سبيل المثال 'posts_per_page' => 500.

اقرأ أيضا: تغيير لون تعليقات الأعضاء المسجليين في ووردبريس

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

add_filter( 'posts_fields', 'posts_fields_custom_variable', 10, 2 ); function posts_fields_custom_variable( $fields, $query ) { global $wpdb; // Only if our custom variable is not false. if ( $query->get( 'limit_fields' ) ) { $fields = "$wpdb->posts.ID, $wpdb->posts.post_title"; } return $fields; } $args = [ 'post_type' => 'post', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'posts_per_page' => 5, // Our custom variable. 'limit_fields' => true, ]; $the_query = new WP_Query( $args );
Code language: PHP (php)

إذا كنا سنحتاج المعرف الوحيد فقط نستعمل البارمتر fields على هذا الشكل

$args = [ 'fields' => 'ids', ];
Code language: PHP (php)

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

اقرأ أيضا: طريقة تعطيل wp rest api

لكن للأسف هذه الدالة لا تستخدم افتراضيا في الإستعلامات المخصصة عبر WP_Query، ويمكننا إضافتها على هذا الشكل

<?php $args = array( 'post_type' => 'post', 'post_per_page' => 5, 'no_found_rows' => true, 'update_post_term_cache' => false, 'suppress_filters' => true, ); $the_query= new WP_Query( $args ); if( $the_query->have_posts() ) { update_post_thumbnail_cache( $the_query); echo '<ul>'; while( $the_query->have_posts() ) { $the_query->the_post(); ?> <li> <h3><?php the_title(); ?></h3> <?php the_post_thumbnail( 'thumbnail' ); ?> </li> <?php } wp_reset_postdata(); echo '</ul>'; }
Code language: PHP (php)

لكن بدل وضع update_post_thumbnail_cache() داخل كل استعلام مخصص، يمكننا إضافة بارامتر مخصص نعطيه القيمة true في كل الإستعلامات التي ستحتوى على صور مصغرة.

add_filter( 'the_posts', 'sb_prime_post_thumbnails_cache', 10, 2 ); function sb_prime_post_thumbnails_cache( $posts, $query ) { if( ! $query->is_main_query() && $query->get( 'sb_upadate_post_thumbnail_cache' ) ) { update_post_thumbnail_cache( $query ); } return $posts; }
Code language: PHP (php)

نستخدمه هكذا

اقرأ أيضا: تعرف على إضافة WP Fastest Cache

$args = [ // Our custom parameter sb_upadate_post_thumbnail_cache' =>; true, ]; $latest_news = new WP_Query( $args );
Code language: PHP (php)

علينا أن نعلم أيضا أن الدالة get_posts() تستخدم داخليا WP_Query و تحدد بعض البرامترات بقيمة مناسبة ك 'no_found_rows' => true، وكذلك تضع 'suppress_filters' => true وهذا يستبعد نتائج الإستعلام من نظام التخزين المؤقت الخاص بووردبريس، لهذا لا تنسى تمريره بالقيمة false في حالة استعمالك ل get_posts() و نفس الأمر مع wp_get_recent_posts() و get_children().

ولكي تكون استعلاماتنا أسرع يجب علينا تجنب قدر الإمكان البحث في جداول متعددة، على سبيل المثال استعلامات حسب تصنيفات (taxonomy) متعددة، استعلامات حسب خصائص إضافة (post meta) متعددة و كذلك الإبتعاد عن البرمترات من نوع __in و not_in كسبيل المثال category__in، category__not_in، post__not_in، tag__not_in … الخ

وفي حالة ضرورة استعمالها من الواجب عمل تخزين مؤقت للإستعلامات.

اقرأ أيضا: كيفية التعديل على الودجة “منوعات”

التخزين المؤقت للإستعلامات في ووردبريس

ووردبريس يوفر لنا واجهتين برمجيتين تمكناننا من عمل تخزين مؤقت لإستعلاماتنا، الأولى WP Object Cache و الأخرى Transients API.

الفرق بينها هو أن الأولى غير مستمرة (non-persistent) حيث يتم تخزين الإستعلام في الذاكرة العشوائية خلال مدة الإستعلام فقط، إذا أردت أن يتم عمل تخزين مستمر ( persistent caching ) عليك استخدام أحد الحلول ك W3 Total Cache، Memcached Object Cache، Redis Object Cache …

وهذا أفضل مثال للإستخدام WP Object Cache في WP_Query

اقرأ أيضا: كيفية عرض المقالات المنشورة خلال الأربع والعشرين ساعة الماضية على ووردبريس

$result = wp_cache_get( 'my_result' ); if ( false === $result ) { $args = array( 'post_type' => 'post', 'tax_query' => array( 'relation' => 'OR', array( 'taxonomy' => 'category', 'field' => 'slug', 'terms' => array( 'quotes' ), ), array( 'relation' => 'AND', array( 'taxonomy' => 'post_format', 'field' => 'slug', 'terms' => array( 'post-format-quote' ), ), array( 'taxonomy' => 'category', 'field' => 'slug', 'terms' => array( 'wisdom' ), ), ), ), ); $query = new WP_Query( $args ); wp_cache_set( 'my_result', $query ); }
Code language: PHP (php)

أما Transients API فتقوم بتخزين نتيجة الإستعلام في قاعدة البيانات، بالتحديد في جدول wp_options عوض تخزينه في الذاكرة، وبهذا يمكننا جلب نتيجة الإستعلام جاهزة في كل مرة وبالتالي تحسين كبير في الآداء وتخفيف العبء على الخادم.

مثال لإستخدام Transients API في WP_Query

$result = get_transient( 'my_result' ); if ( false === $result ) { $args = array( 'post_type' => 'post', 'tax_query' => array( 'relation' => 'OR', array( 'taxonomy' => 'category', 'field' => 'slug', 'terms' => array( 'quotes' ), ), array( 'relation' => 'AND', array( 'taxonomy' => 'post_format', 'field' => 'slug', 'terms' => array( 'post-format-quote' ), ), array( 'taxonomy' => 'category', 'field' => 'slug', 'terms' => array( 'wisdom' ), ), ), ), ); $query = new WP_Query( $args ); set_transient( 'my_result', $query, HOUR_IN_SECONDS ); }
Code language: PHP (php)

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

اقرأ أيضا: كيفية وضع اﻹعلانات في أي مكان تريده على ووردبريس

MINUTE_IN_SECONDS = 60 (seconds) HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS MONTH_IN_SECONDS = 30 * DAY_IN_SECONDS YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS
Code language: PHP (php)

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

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

الكود في هذه الحالة سيكون كالتالي :

اقرأ أيضا: عرض آخر المستخدمين المسجلين على ووردبريس

$fb_count = get_transient('facebook_count'); if ( false === $fb_count ) { $return = wp_remote_get( 'http://graph.facebook.com/?id=http://www.mysie.com', array( 'timeout' => 10 ) ); $json = json_decode($return["body"], true); $fb_count = isset($json["shares"]) ? intval($json["shares"]) : 0; set_transient('facebook_count', $fb_count, 5 * MINUTE_IN_SECONDS); }
Code language: PHP (php)

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

شكرا لك على الوصول إلى نهاية التدوينة 🙂


close

سعيد نورتي

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *