کوئری گرفتن از دیتابیس بزرگ

من یه جدول از یه دیتابیس (mariadb) دارم که الآن حدود نیم ملیون رکورد داره و دوتا پروژه (دوتا نرم افزار کاملا مجزا) بهش دسترسی دارن.

هر دقیقه یه رکورد بهش اضافه میشه. (پروژه‌ی ۱)
نیاز هست که از این دیتاها خروجی json و یه سری نمودار Html گرفته بشه. (از طریق یه وبسایت - پروژه‌ی ۲)

پروژه‌ی ۱ اصلا هیچ فشاری به سرور نمیاره که کاملا طبیعیه و اصلا دیگه حرفی درموردش نمیزنیم.
پروژه‌ی ۲ توی هر بار اجرا شدن باید تمام دیتابیس رو بخونه و یه Html بسازه و یا خروجی json بهمون بده. (حجم فایل json بالای ۵۰۰مگابایته و هر روز ۳مگابایت بهش اضافه میشه)

وقتی پروژه‌ی ۲ اجرا میشه تمام رم سرور (۴گیگ) پر میشه و به خاطر کند بودن رم سرور، بیشتر از ۳۰ثانیه طول میکشه و timeout میگیرم از Nginx. (تمام دیتابیس کوئری گرفته میشه و یه مقدار روش پردازش انجام میشه)

سوال من اینه که این مساله مربوط به دیتابیس میشه؟ (چه دیتابیسی بهتره استفاده کنم؟)
یا مربوط به نرم افزاره؟ (بیشتر از این قابل بهینه سازی نیست!)

اگر مربوط به نرم افزار میشه، روش خاصی برای بهینه سازی هست؟ یا مثل پردازش عکسهای بزرگ، حتما نیاز به رم زیاد وجود داره؟ (از پایتون استفاده میکنم و تعداد متغیرهام حداقل ممکنه)
تنها روشی که به ذهن خودم میرسه اینه که مثل لاگ‌فایل، تیکه تیکه کنم و مثلا هر ۱۰۰۰تا رکورد رو توی یه فایل سیو کنم. (یا به جای یه کوئری، چندتا کوئری بزنم.)
به خاطر یه مشکل فنی خارج از سرور، دریافت دیتا (پروژه‌ی ۱) از کار افتاد و مجبور شدم از اول همه چیز رو ریست کنم (جدول دیتابیس رو پاک کردم و از اول شروع کردم به جمع کردن دیتا) و رم سرور رو به ۱۰گیگ ارتقاع دادم ولی اصلا فکر نمیکنم ارتقاع سخت‌افزار مشکل اصلی بوده باشه.

1 پسندیده

۵۰۰ مگ خیلی داده نیست و من اول نگاه می‌کردم به query ها داده رو در batch
2000 تا یا بیشتر میگرفتم بعد ببین با explain
Query داره چیکار میکنه اگر ایندکسی نیاز داره اضافه کن
اگر اینها کار نکرد میتونی query با view از قبل آماده کنی و جوابشو ذخیره کنی تا در زمان نرمال app اول دیتابیس نیاره پایین
راه دیگه اینکه یک replica مخصوص app ۲ بگذاری

2 پسندیده

انجین ایکس تایم آوت بخصوصی نداره … اگه از gunicorn استفاده میکنی دیفالت تایم آوت روی 30ثانیه هست … و اگر از uWSGI احتمالا 60ثانیه … و انجین ایکس صرفا این تایم آوت رو میگیره بخاطر قطع ارتباط… به شما پیام تایم اوت رو میفرسته … .

قابلیت بهینه سازی ک همیشه هست ; D … اگر ormمیزنید … با raw SQL امتحان کنید … orm عمده کارش روی رم هست … و دقیقا اگر رم بیشتری بهش بدید … بهبود پرفورمنس بالایی بهتون میده …

این تکنیک تیکه تیکه کردن … یا به عبارتی shard partition خیلی موثر هست … و روی همون دیتابیست میتونی انجامش بدی … ک بصورت سینگل فایل ذخیره نکنه … و تیکه تیکش کنه . .

1 پسندیده

اینو میدونم ولی مساله اینه که اصلا نباید اینقدر طول بکشه و نمیخوام از مساله فرار کنم. ۵۰۰مگ دیتابیسو نتونم هندل کنم باید برم بمیرم.

مساله اینه که کد خیلی سادست و تنها چیزی که لازمه اینه که متغیر اضافی ساخته نشه. که مشکلی از این بابت نیست.
برای بهینه‌سازی بیشتر، فقط باید صبر کنم دیتا یه کم بیشتر بشه بعد برم روشهای دیگه‌رو تست کنم.
درمورد ORM خیلی ممنون! نمیدونستم. حتما core api رو تست میکنم.

از اونجایی که دیتاهای قبلی اصلا ویرایش نمیشن، حتی میشه از دیتابیس پاکشون کرد. یعنی توی فایلهای ده‌هزارتایی کوئری‌ها رو تیکه تیکه کنم و از دیتابیس پاک کنم.

چیزی که برام عجیب بود اینه که ۵۰۰مگ نباید اینقدر اذیت کنه.
حالا فعلا که دیتا خیلی کمه. یه ماه دیگه که سنگین شد برم روی پروداکشن ادیت کنم :slight_smile:
ممنون بابت raw SQL

1 پسندیده

اصلا راجبه اینکه حجم دیتابیس چقدره دچار پریشونی نشید :grin: حجم صرفا یکی از ایتم هاست … میزان بعدی… فراوانی احتمالات هست…
وقتی 500مگ دیتا دارید . ک قراره بکشید بیرون … و رو همشون یه پروسس های مختلف / سورت / دسته بندی و… و… انجام بدید … طبیعیه زمان ببره …

منظورم از بهینه سازی… صرفا کد نبود … بلکه منطقی هم میشه … مثلا ما دیتاهامون فیلمن … و نیاز داریم مثل سایر پلتفرما و یوتیوب … کیفیت های مختلفی رو ارائه بدیم … و همینطور… استریم بکنیم … بجای دادن آدرس اصلی…

راهکار اولیه استفاده از سیستمایی مثل woowza و مشابهات بود … ک خب… اینها دارن روی رم اینکارو میکنن!! و بصورت real time … ک مصرف رم بشدت بالا میره … راه کاری ک انجام دادم این بود ک . .بعد از آپلود ویدیو … کانورت و چانک کردن رو انجام میدادم و رو هارد ذخیره میکردم … و به همین راحتی با مینیمم رم … تونستم کیفیت های مختلفی رو صرفا با خوندن چانک های کوچیک از هارد … هندل کنم … هارد خیلی خیلی ارزون تر از رم هست : )

شما هم باید ببینید … اگر شدنیه … و احتمالات محدودی هست برای نمودار و داده هاتون … میتونید preprocess بکنید … یا به نوعی pagination … ک کاربر اول یه چیزی ک مهمه دریافت کنه … بعد الباقی … تکنیک زیاده …

اگر فراوانی داده هاتون خیلی بالاست و حجمشون قراره بالاتر بره یا بدون ساختار هستن دیتاها/نتایج … خب مسلما تعویض دیتابیس… و چیزی مثل مونگو بشدت کمک میکنه برای سرچ … و واکشی …

و همینطور نکته ای ک قابل تامله اینه ک . .شماحداقل یه پرینت بزارید . .ببینید ک io دیتابیسه ک اذیت میکنه یا ioهارد موقع write و ایجاد اون فایل json … ک اگر هارد باشه … راه کارش استفاده از ssd/nvme هست

2 پسندیده

ممکنه نیاز به بهینه سازی application داشته باشید، دیتابیس شما خیلی بزرگ نیست، اگر من بودم به جای تغییر فناوری اول مطمئن میشدم که کوئری ها بهینست، مثلا چک کنید که مشکل Query N+1 نداشته باشید، و اگر دارید برای برطرف کردنش دیتای زیادی بافر نکنید چون گاهی بافر کردن رکورد ها برای از بین بردن این مشکل خودش تبدیل به مشکل میشه. کلا منظورم بهینه سازی هست، مهاجرت به stack دیگه باید آخرین راهکار باشه

1 پسندیده

حقیقتش این سیستمی که ران کردم دیتای قیمت و ۲۴تا فاکتور دیگه مربوط به بیت کوین رو ذخیره میکنه و هدفم «داشتن دیتا برای deep learning» هست. یعنی این قضیه‌ی دیتابیس کلا هاشیه به حساب میاد.
ولی توی سوال جوابهای این صفحه، خیلی چیزها یاد گرفتم و توشه‌ای برای آینده کسب کردم :innocent:

این نکته‌ی خیلی مهمی بود. ممنون!

نه تنها شدنیه بلکه توی این کاری که من دارم انجام میدم کاملا هم منطقی هست. فقط فکر نمیکردم نیازی بهش باشه. فکر نمیکردم با این حجم دیتا مجبور باشم سراغ همچین چیزهایی برم. (مثلا اینکه ۱۰۰۰تا ردیف جدول رو بفرستم وقتی کاربر اوکی داد ۱۰۰۰تا دیگه بفرستم) فکر میکردم این فقط برای سیستمهایی لازمه که دارن سرویس ارائه میدن به چند هزار کاربر (این سیستم فقط یه کاربر داره اونم خودمم!)
پس مثل اینکه اینجا هم لازمه.

نه. خیلی خوش و خرم کنار هم نشستن توی جدول.
البته به زودی یه بخش اضافه میکنم که اخبار روزنامه‌های جهان رو جمع کنه برای پردازش متن. (هیچ چیز به اندازه‌ی اخبار روی قیمت بیت کوین اثر نمیذاره. مردم خیلی سریع ذوق زده و یا وحشت زده میشن) که در این مورد باید بیشتر فکر کنم. شاید در کنار mysql یه nosql نگه دارم. شاید هم نیازی نباشه.

خیلی ممنون. اینم نکته‌ی مهمی بود.

نکته‌ی خوبی بود. حتما اینم بررسی میکنم.

2 پسندیده