بهینه‌سازی دیتابیس؛ از یک پارکینگ شلوغ تا یک اتوبان تندرو

احتمالاً برایتان پیش آمده که سایت یا اپلیکیشن‌تان در ساعات پیک ترافیک، دچار کندی شدید شود و مانند خودرویی فرسوده در ترافیک سنگین تهران، از حرکت بازماند. بسیاری از ما نخستین واکنشمان ارتقای هاست یا سرور است، بدون آنکه ریشهٔ اصلی را بشناسیم و هزینه‌های ماهانه را بی‌دلیل افزایش می‌دهیم. اما باید اشاره کنم که نزدیک به ۸۰ درصد افت عملکرد نرم‌افزارها، ناشی از یک دیتابیس بهینه‌نشده است. در این مقاله قصد نداریم با فرمول‌های پیچیده یا کدهای دلهره‌آور سر و کار داشته باشیم؛ بلکه با زبانی ساده و مثال‌های عینی، یاد می‌گیرید که دیتابیس خود را از یک پارکینگ شلوغ به یک اتوبان پرسرعت تبدیل کنید.

۱. ایندکس‌گذاری (Indexing)؛ یعنی فهرست کتابخانه!

فرض کنید کتابخانه‌ای با ۵۰ هزار جلد کتاب دارید و یک بازدیدکننده به‌دنبال کتاب «سه‌شنبه‌ها با موری» می‌گردد. اگر کتاب‌ها بدون نظم چیده شده باشند، شما و بازدیدکننده مجبورید تک‌تک قفسه‌ها را ورق بزنید تا بالاخره آن را پیدا کنید. این دقیقاً همان کاری است که دیتابیس بدون ایندکس انجام می‌دهد (Full Table Scan). اما اگر یک فهرست الفبایی (ایندکس) روی ستون «عنوان کتاب» داشته باشید، در کمتر از یک ثانیه کتاب را تحویل می‌گیرید.

چه ستون‌هایی را حتماً ایندکس کنیم؟

نیازی نیست همهٔ ستون‌ها را ایندکس کنید، چون خودِ ایندکس هم حافظه می‌خورد! قانون طلایی این است: هر ستونی که در عبارت‌های WHERE، JOIN (مثل کلیدهای خارجی) یا ORDER BY به‌طور مکرر استفاده می‌شود، کاندیدای مناسبی برای ایندکس‌گذاری است. مثلاً در یک سایت فروشگاهی، ستون product_id یا user_id را حتماً باید در اولویت قرار دهید.

۲. با کوئری‌های سنگین خداحافظی کنید (قانون SELECT *)

یکی از عادت‌های بدی که حتی برخی از برنامه‌نویسان حرفه‌ای هم دارند، استفاده از عبارت SELECT * است. بیایید یک مثال جذاب بزنیم: فرض کنید برای خرید یک عدد تخم‌مرغ به فروشگاهی می‌روید، اما فروشنده اصرار دارد که تمام قفسه‌های یخچال را با کامیون به خانه شما حمل کند! قطعاً این کار هم هزینه دارد و هم زمان‌بر است. کوئری SELECT * دقیقاً همین کار را می‌کند؛ تمام ستون‌های یک جدول را واکشی می‌کند، حتی اگر شما فقط به نام کاربر و ایمیلش نیاز داشته باشید.

راهکار ساده چیست؟

همیشه فقط ستون‌هایی را که واقعاً به آن‌ها نیاز دارید، در کوئری بنویسید. مثلاً به‌جای SELECT * FROM users بنویسید SELECT id, name, email FROM users. این کار حجم داده‌های منتقل‌شده را تا ۵۰ درصد کاهش می‌دهد و فشار زیادی از روی رم و پردازنده سرور برمی‌دارد.

۳. کش (Caching)؛ مغز کمکی دیتابیس!

آیا تا به حال برای شما پیش آمده که یک مطلب تکراری را روزی ۱۰۰ بار برای دوستانتان تعریف کنید و خسته شوید؟ دیتابیس هم دقیقاً از این کار خسته می‌شود! بسیاری از کوئری‌های ما تکراری هستند (مثل نمایش صفحات اصلی وب‌سایت یا اطلاعات پروفایل کاربران). اینجا جایی است که «کش» (Cache) مثل یک مغز کمکی وارد می‌شود.

با فعال کردن ابزارهایی مثل Redis یا Memcached یا حتی کش‌های سطح اپلیکیشن (مثل کش کوئری در وردپرس)، نتیجهٔ کوئری‌های سنگین را در حافظهٔ موقت ذخیره می‌کنیم. دفعهٔ بعد که کاربر درخواست مشابهی داد، دیگر دیتابیس زحمت محاسبه مجدد را نمی‌کشد و نتیجه را در کسری از میلی‌ثانیه از کش تحویل می‌دهد. مثل این می‌ماند که غذای دیشب را یخچال بگذارید و امروز فقط گرمش کنید؛ بی‌نیاز از پخت مجدد!

۴. نظافت و سرویس‌کاری دوره‌ای را فراموش نکنید

دیتابیس هم مثل خانه نیاز به جارو کشیدن دارد! با گذشت زمان، رکوردهای حذف‌شده، لاگ‌های اضافی و داده‌های بی‌استفاده (مثلاً نشست‌های قدیمی کاربران) در جدول‌ها انباشته می‌شوند. این داده‌ها نه‌تنها فضا اشغال می‌کنند، بلکه سرعت اسکن‌ها را نیز کاهش می‌دهند.

چطور این کار را انجام دهیم؟

اگر از MySQL استفاده می‌کنید، دستور OPTIMIZE TABLE را در نظر بگیرید. همچنین پاک‌سازی دوره‌ای لاگ‌ها و داده‌های بی‌کاربرد (مثلاً حذف خودکار رکوردهای مربوط به ۶ ماه پیش) می‌تواند معجزه کند. برای وب‌سایت‌های وردپرسی، پاک‌سازی گزینه‌های آپشن (autoload) و جدول‌های موقت، یکی از سریع‌ترین راه‌ها برای افزایش سرعت دیتابیس است.

۵. تنظیمات سرور را با نیازهایتان هماهنگ کنید

بسیاری از مدیران سرور، دیتابیس را با تنظیمات پیش‌فرض (Default) رها می‌کنند، درست مثل کسی که کت و شلوار تنگِ دیگری را پوشیده باشد! برای MySQL، پارامترهایی مثل innodb_buffer_pool_size نقشی حیاتی دارند. اگر سرور شما رم آزاد دارد، این مقدار را افزایش دهید تا دیتابیس بتواند صفحات بیشتری را در حافظه نگه دارد و از خواندن دیسک (که بسیار کند است) خودداری کند.

یک مثال ملموس: فرض کنید دارید از یک یخچال بزرگ (سرور با رم بالا) استفاده می‌کنید، اما یک دربازکن کوچک ۵۰ لیتری (تنظیمات کم) داخل آن گذاشته‌اید! حتماً با توجه به میزان رم و سی‌پی‌یو سرور، فایل تنظیمات (my.cnf یا my.ini) را به‌روز کنید. افزایش محدودیت‌های اتصال همزمان (max_connections) نیز از بروز خطای «Too many connections» در ساعات شلوغی جلوگیری می‌کند.

جمع‌بندی؛ از امروز شروع کنید!

بهینه‌سازی دیتابیس یک علم پیچیده نیست، بلکه بیشتر شبیه به یک هنر ساده‌ی مدیریتی است. لازم نیست همهٔ نکات را یک‌باره پیاده‌سازی کنید. فقط کافی است امروز با قانون SELECT * شروع کنید و فردا یک ایندکس جدید به جدول پربازدیدتان اضافه کنید. حتی همین تغییرات کوچک، تأثیرش را در کاهش زمان بارگذاری صفحات به‌خوبی نشان خواهند داد. یادتان باشد که کاربران امروزی، بیش از ۳ ثانیه برای بارگذاری یک صفحه منتظر نمی‌مانند؛ پس اجازه ندهید دیتابیس شما، قاتل فروش یا مخاطبان‌تان باشد. اگر سؤالی دربارهٔ مرحلهٔ خاصی دارید، خوشحال می‌شوم در کامنت‌ها به آن پاسخ دهم!