ftp
5 سال پیش توسط ftp مطرح شد
15 پاسخ

بهینه کردن کوئری

@ali.bayat

من یک سوال داشتم
الان من حدود ۶۰۰۰۰۰ رکورد در دیتابیس mysqlدارم و وقتی میخوام تعداد این رکورد ها رو در بیارم حدود ۱ دقیقه طول میکشه تا جواب رو به من بده باید برای رفع اینچنین مشکل چیکار کرد من ایندکس گذاری هم کردم اما باز نتیجه همونه منظور از مشکل تایمش رو میگم چون زمان زیادی میبره؟ممنون میشه راهنمایی کنید


ثبت پرسش جدید
نوب
تخصص : کدنویس نوب :)
@yk5742g 5 سال پیش مطرح شد
0

اگر میخواید همه رکوردها را توی یه صفحه ببینین که به نظر من کلا غلطه چون سرور میترکه 😂

باید paginate کنین خب تا فشار روی سرور نیاد و راحت کوئری بگیرین و برای پیدا کردن راحت کوئریتون هم یه فرم جستجو بنویسین.

مورد بعدی اینکه این رکوردهاتون چندتا ستون داره و دارین چندتا ستونشو query میگیرین؟
اگر تعداد ستون های دیتابیستون زیاده پیشنهاد میکنم خوردش کنین توی 2 یا 3 تا table و join بزنین بهشون و foreign key براشون بزنین

اینا چیزایی بود که به دانش خیلی کم برنامه نویسی من خطور میکرد.
قطعا دوستان راه های بهتری میتونن پیشنهاد بدن


ftp
تخصص : ساده
@ftp 5 سال پیش مطرح شد
0

@yk5742g
یاسین جان منظورم این نیست منظورم اینکه میخواهم تعداد کل رکوردها رو بدست بیارم اما زمان زیادی طول میکشه چیزی نمیخوام نشون بدم فقط تعداد رکوردهایی که در جدول وجود دارد رو به ما بگه نه این که همه رو نشان بده


نوب
تخصص : کدنویس نوب :)
@yk5742g 5 سال پیش مطرح شد
0

اگر منظورت اینه که بگه مثلا 65000 تا سطر وجود داره از تابع count خود لاراول استفاده کن اخر کوئری به اینصورت ->count()
از تابع count خود php استفاده نکن


ftp
تخصص : ساده
@ftp 5 سال پیش مطرح شد
0

@yk5742g
اینا رو میدونم مشکل من سر دیر نمایش دادن هست لود نتیجه طولانی هست چه تکنیکی باید رعایت شود تا سرعت لود کم شه


محمدحسن یگانه
تخصص : Full-Stack Web Developer Freel...
@mhyeganeh 5 سال پیش مطرح شد
0

@mehdisut
دوست عزیز؛ بدون دیدن کد کوئری و آشنایی با ساختار دیتابیستون هیچ نظر قطعی و کمک کننده ای نمیشه داد. اصلا مشخص نکردید که قصد چجور کوئری گرفتنی دارید؟ ساختار دیتابیس و جدولتون به چه شکله؟ حتی میزان منابع سخت افزاریتون هم حائز اهمیت خواهد بود ر این شرایط. صرفا تعداد رکوردها رو اشاره کردید که خیلی قضیه مهمی شاید نباشه.

روش های خیلی مختلفی میتونه کمک کننده باشه برای کاهش زمان لازم بری اجرای کوئری. مثل جلوگیری از خطای N+1 کوئری با استفاده از Eager loading یا index گذاری صحیح روی ستون های خاص یا استفاده از برخی دستورات خاص در query builder یا ...

خلاصه اینکه بدون دیدن کد کوئری و همچنین ساختار دیتابیستون (مثلا فایل migration) نیمشه نظر داد.


ftp
تخصص : ساده
@ftp 5 سال پیش آپدیت شد
0

@mhyeganeh
من دستور ساده

Model::count()

رو اجرا کردم برای تعداد رکوردها همین چیزی به عنوان ایندس گذاری انجام ندادم اگه میشه در این رابطه توضیح و در مورد خطای n+1توضیح بدید و الان من باید چیکار کنم


وحید
تخصص : Fullstack
@forughi.vahid 5 سال پیش آپدیت شد
0

@mehdisut
احتمال داره مشکل از رمتون باشه ، البته من نمیدونم کانت که میگیریم دقیقا چه اتفاقی توی سرور میفته و چجوری عمل میکنه ، دوستان اگه میدونن راهنمایی کنن که با دید باز تری جلو بریم ولی اگر مشکل از ظرفیت رم باشه مشکل شما با chunk حل میشه :

$count = 0;
Model::chunk(1000, function($models) use(&$count){
   $count += $models->count();
})

محسن بستان
تخصص : Senior Backend Developer
@mohsenbostan 5 سال پیش مطرح شد
0

@mehdisut
سلام.
تنها راه حل و بهترین راه حل استفاده از Lazy Collection هستش که در لاراول 6 اضافه شد.
https://roocket.ir/series/whats-new-in-laravel-6/episode/5
https://roocket.ir/series/whats-new-in-laravel-6/episode/6


ftp
تخصص : ساده
@ftp 5 سال پیش مطرح شد
0

@mohsenbostan
ایا Eager loading با Lazy Collection فرق میکند


محسن بستان
تخصص : Senior Backend Developer
@mohsenbostan 5 سال پیش مطرح شد
0

@mehdisut
بله خیلی فرق می کنه.
اون ویدیو ها رو ببینید.


ftp
تخصص : ساده
@ftp 5 سال پیش مطرح شد
0

@mohsenbostan
من در قسمتی از join استفاده کردم. خیلی سرعتو پایین میاره ایا راهی هست جایگزینی برای این متدد وجود دارد

کدم اینه

$t = DB::table('form_tools')
                ->join('enable', function ($join) {
                    $join->on('form_tools.form_id', '=', 'enable.form_id')
                        ->on('form_tools.admin_id', '=', 'enable.admin_id')
                        ->on('form_tools.tool_name', '=', 'enable.if_i');
                })->get();

محسن بستان
تخصص : Senior Backend Developer
@mohsenbostan 5 سال پیش مطرح شد
0

@mehdisut
به جای همه join از where استفاده کنید.
و همچنین به جای DB از مدل استفاده کنید.


ftp
تخصص : ساده
@ftp 5 سال پیش مطرح شد
0

@mohsenbostan
میشه نمونه کد بدید


محسن بستان
تخصص : Senior Backend Developer
@mohsenbostan 5 سال پیش مطرح شد
0

@mehdisut
من الان نمیدونم شما قراره چی کار بکنید. بهتره که مستندات رو مطالعه کنید.
where و whereHas


محمدحسن یگانه
تخصص : Full-Stack Web Developer Freel...
@mhyeganeh 5 سال پیش مطرح شد
0

@mehdisut
یک جایی در پیام های بالا گفتید که فقط دارید از دستور count() به شکل ساده روی مدل استفاده می‌کنید و یک جای دیگه یک کوئری ۶ خطی گذاشتید. بالاخره کدومش؟

چیزی که قعطیه این هست که دستور صرف count() هر چقدر هم که حجم داده تون زیاد باشه زمان زیادی نیاز نداره و خیلی ساده هست و احتیاجی به lazy collection و chunk نیست. هر اتفاقی که می افته داره در بخش مربوط به کوئری و join زدن و ... این ها اتفاق می افته و برای اظهار نظر در این مورد هم همون طوری که عرض کردم باید ساختار جداول مروبوطه و عبارت دقیق کوئری تون بررسی بشه.

برای اطلاعات بیشتر در مورد خطای N+1 هم گوگل کنید پاسخ های مفصل زیادی وجود داره:
https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام