Laravel / المتقدم / الدرس 15
أداء الاستعلامات والفهارس
حقق عدد الاستعلامات والبيانات ومسارات الوصول بحمل معلوم بدل اعتبار الفهرس أو التحميل المسبق ضمان سرعة عامًا.
في هذه الصفحة
أهداف الدرس
- تمييز N+1 وحفظ مفاتيح العلاقة عند اختيار الأعمدة.
- تصميم فهارس مركبة مرشحة من الشروط والترتيب الفعليين.
- فصل اختبارات البنية عن أدلة خطة التنفيذ.
تحديد الطلب ونموذج بياناته
تضم التجربة posts بحقول id وtenant_id وauthor_id وstatus وtitle وusers بمعرّف واسم، وعلاقة author belongsTo. يطلب مستأجر مصرح خمسين منشورًا منشورًا بترتيب id وأسماء المؤلفين. قِس عدد الاستعلامات والزمن والصفوف والأعمدة والعرض؛ فقد يبطؤ غير SQL أو يتكرر استعلام سريع لكل صف. لا يمس الدرس قاعدة أو ترحيلًا أو خطة فعلية.
تجميع الوصول للعلاقات بدل تكراره
قد تنشئ قراءة العلاقة داخل الحلقة N+1. يقارن نموذج PHP طلبًا لكل منشور بطلب مجمع للمعرّفات المتميزة؛ لا يعد SQL فعلية. يجمع التحميل المسبق صفوف العلاقة ويجب حفظ المفاتيح الأساسية والخارجية. قد يحذف اختيار title فقط author_id فيفشل الربط. اختبر العلاقة ونطاقاتها؛ فتغيّر العلاقات المتعددة والخطافات والداخل الميزانية الفعلية.
<?php
declare(strict_types=1);
$posts = [
["id" => 1, "author_id" => 7],
["id" => 2, "author_id" => 7],
["id" => 3, "author_id" => 9],
];
$authorIds = array_values(array_unique(array_column($posts, "author_id")));
echo "individual=", count($posts), " batch=", (count($authorIds) > 0 ? 1 : 0), PHP_EOL;
echo json_encode($authorIds, JSON_THROW_ON_ERROR), PHP_EOL;
individual=3 batch=1
[7,9]
تحتاج الثلاثة ثلاث طلبات منفردة ويمكن جمع المعرّفين 7 و9. لا يدّعي الناتج قياس سلوك قاعدة.
حفظ المفاتيح مع تحديد النتيجة
يحفظ الاستعلام مفاتيح ربط المؤلف ويحد صفوف الأصل. يأتي المستأجر المفحوص من الإذن لا حقل طلب موثوق اعتباطيًا. العلاقة والمخطط شرطان معلنان. لا يُنفذ المقطع ولا تُختلق صفوف أو أزمنة. يهدف التحميل لعلاقة belongsTo العادية إلى طلب علاقة واحد بدل التكرار؛ افحصه بقاعدة معزولة. لا يضمن limit مسار وصول فعالًا.
<?php
use App\Models\Post;
$posts = Post::query()
->where("tenant_id", $authorizedTenantId)
->where("status", "published")
->with("author:id,name")
->orderBy("id")
->limit(50)
->get(["id", "author_id", "title"]);
المتوقع في التجربة المعلنة: حفظ id وauthor_id واستخدام المؤلف المحمل. يتبع العدد والخطة إعداد النموذج الكامل.
اشتقاق فرضية فهرس من الشروط والترتيب
قد يدعم فهرس tenant_id وstatus وid الشروط والترتيب، ويسجل المقطع فرضية لا مثالية. تؤثر الآلة والمقارنة والتوزيع والانتقائية والفهارس والكتابة. افحص الخطة والوقت في قاعدة معزولة مصرح بها. تستهلك الفهارس مساحة وتزيد كلفة كتابة، فلا تضف كل تبديل. قد يكلف offset العميق وتحتاج صفحة المؤشر ترتيبًا ثابتًا وشروطها.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table("posts", function (Blueprint $table): void {
$table->index(["tenant_id", "status", "id"], "posts_tenant_status_id_idx");
});
يعلن المقطع فهرسًا مركبًا ضمن ترحيل مصرح للجدول، ولا يُشغّل أو يضمن اختيار الفهرس أو السرعة.
فحص الطلب كاملًا لا عبارة واحدة
اختبر عددًا محدودًا والعلاقة وفصل المستأجر. استخدم الرصد بحذر دون معاملات حساسة خام. قد تحتاج الصادرات chunkById أو lazyById خصوصًا عند تغيير الصفوف الممسوحة، مع تصميم الذاكرة والترتيب والمعاملة والكتابة المتزامنة. أعد فحص الناتج وكلفة الكتابة بعد الفهرس ولا تنسب EXPLAIN أو قياسًا لم تنفذه؛ سمّ المقترح غير المقاس فرضية.
الأخطاء الشائعة وإصلاحها
عرض كل منشور يضيف استعلام مؤلف.
- لماذا يحدث؟
- يشغّل العرض تحميلًا كسولًا داخل الحلقة.
- كيف تصلحه؟
- حمّل العلاقة مسبقًا واحفظ مفاتيح المطابقة.
- كيف تتجنب تكراره؟
- اختبر نمو الاستعلامات بزيادة الصفوف.
استعلام أعمدته منتقاة يفقد المؤلف.
- لماذا يحدث؟
- أُغفل المفتاح الخارجي للعلاقة.
- كيف تصلحه؟
- ضمّن مفاتيح الأصل والعلاقة اللازمة.
- كيف تتجنب تكراره؟
- راجع الاختيار باختبارات علاقة.
فهرس إضافي يبطئ الكتابة دون فائدة.
- لماذا يحدث؟
- قُبل المرشح دون دليل حمل وخطة.
- كيف تصلحه؟
- قِس التجربة المصرحة وقارن القراءة والكتابة.
- كيف تتجنب تكراره؟
- عامل الفهرس فرضية مختبرة لا قاعدة عامة.
اختبر فهمك
1. أضف منشورًا رابعًا للمؤلف 7. حدّد العدّين ولماذا ليسا عدد Eloquent الفعلي.
اعرض الحل المشروح
تصبح المنفردة أربعًا وتبقى دفعة واحدة للمعرّفين. يستبعد النموذج استعلام الأصل والاتصال والنطاق والخطافات والداخل. عدّ الطلب الحقيقي بإعداداته بدل تحويل النموذج لتأكيد عام.
2. يضاف مرشح category_id. هل يستبدل الفهرس دائمًا بالترتيب الموسع؟ حدّد الدليل.
اعرض الحل المشروح
لا. قارن التكرار واختيارية المرشح والانتقائية والترتيب والفهارس وكلفة الكتابة وخطط المحرك. اختبر بيانات ممثلة معزولة وصحة الناتج. قد يفيد الأطول نمطًا ويضر غيره أو يكرره؛ ويقرر الحمل التصميم المبرر.
أهم ما تعلمته
- قِس نمو الاستعلامات واحفظ مفاتيح العلاقة.
- حد النتيجة دون افتراض سرعة الوصول.
- تحتاج الفهارس دليل المحرك ومراجعة الكتابة.