کارایی پایگاه داده: چرا همیشه اول اینجا کم میآید

وقتی سامانهای کند میشود، اولین حدس معمولاً «سرور کم آورده» است. در بیشتر مواردی که دیدهایم، حدس غلطی است: پردازنده بیکار است، حافظه آزاد است، و سامانه منتظر پایگاه داده ایستاده.
دلیلش ساده است. لایهٔ برنامه معمولاً بهراحتی افقی مقیاس میگیرد — یک نمونهٔ دیگر بالا میآورید. پایگاه دادهٔ نوشتنی اینطور نیست. همان تکنقطهای است که همه به آن میرسند.
چرا کندی ناگهانی میآید
سامانهای که دو سال روان کار کرده، در یک هفته کند میشود بدون اینکه کدی عوض شده باشد. این الگو آنقدر تکرار میشود که ارزش توضیح دارد.
پایگاه داده برای هر پرسوجو یک نقشهٔ اجرا انتخاب میکند. تا وقتی جدول کوچک است، خواندن کل جدول ارزان است و بهینهساز همان را انتخاب میکند — سریع و بیمسئله. از یک اندازه به بعد، همان انتخاب فاجعه است.
یعنی پرسوجوی بد از روز اول بد بوده؛ فقط تا امروز اثرش دیده نمیشد. و به همین دلیل است که تست بار روی پایگاه دادهٔ کوچک عملاً هیچ چیزی را تست نمیکند.
اول: بدانید کدام پرسوجو کند است
بدون داده، بهینهسازی حدس است — و حدس معمولاً سراغ کدی میرود که زشت به نظر میرسد، نه کدی که کند است.
سه چیز را روشن کنید:
لاگ پرسوجوهای کند. تقریباً هر پایگاه دادهٔ جدی این را دارد و معمولاً خاموش است. آستانهای بگذارید و یک هفته جمع کنید.
نه فقط کندترین، پرتکرارترین. پرسوجویی که ۸۰۰ میلیثانیه طول میکشد و روزی سه بار اجرا میشود، مسئلهٔ شما نیست. پرسوجویی که ۳۰ میلیثانیه طول میکشد و در هر بارگذاری صفحه ۲۰۰ بار اجرا میشود، مسئلهٔ شماست. ملاک، حاصلضرب زمان در تعداد است.
نقشهٔ اجرا. هر پایگاه دادهای میتواند بگوید برای یک پرسوجو چه کرده. خواندن این خروجی مهارتی است که یک بعدازظهر یاد گرفتن دارد و سالها به کار میآید. کلمهٔ کلیدیای که دنبالش میگردید: پیمایش کامل جدول، جایی که انتظار داشتید از ایندکس استفاده شود.
دوم: ایندکس، و سه چیزی که دربارهٔ آن گفته نمیشود
ایندکس بیشترین بازده را در کمترین زمان دارد. ولی سه نکته:
ترتیب ستونها در ایندکس ترکیبی اهمیت دارد. ایندکسی روی (سازمان، تاریخ) به پرسوجویی که فقط بر اساس تاریخ فیلتر میکند کمک نمیکند. این تنها اشتباه ایندکسگذاری است که بیش از همه دیدهایم.
ایندکس هزینهٔ نوشتن دارد. هر درج و بهروزرسانی باید همهٔ ایندکسها را هم بهروز کند. جدولی با دوازده ایندکس، جدولی است که کسی برای خواندن بهینه کرده و برای نوشتن خراب.
ایندکس بلااستفاده بدتر از نبودنش است. هزینه دارد و فایده ندارد. اکثر پایگاههای داده آمار استفاده از ایندکس را نگه میدارند؛ سالی یک بار نگاه کنید و ایندکسهای صفرمصرف را حذف کنید.
سوم: مسئلهٔ N+1
شایعترین الگوی کندی در سامانههای سازمانی، و تقریباً همیشه از لایهٔ نگاشت شیء‑رابطهای میآید.
فهرست صد سفارش را میخوانید. بعد برای هر سفارش، نام مشتری را میگیرید. یک پرسوجو برای فهرست، صد پرسوجو برای مشتریها. در محیط توسعه با ده رکورد، هیچ کس متوجه نمیشود.
راه تشخیصش ساده است: تعداد پرسوجوهای هر درخواست را لاگ کنید. صفحهای که بیش از بیست پرسوجو میزند، تقریباً همیشه این مسئله را دارد. این عدد را در محیط توسعه نشان دادن، ارزانترین ابزار پیشگیری است که میشناسیم.
چهارم: صفحهبندی و گزارش
دو الگوی دیگر که با رشد داده منفجر میشوند:
صفحهبندی با پرش. «صفحهٔ ۵۰۰۰ را بده» یعنی پایگاه داده باید ۵۰ هزار ردیف را بخواند و دور بریزد. برای فهرستهای بلند، صفحهبندی مبتنی بر مکاننما («بعد از این شناسه») هزینهٔ ثابت دارد.
گزارشی که روی پایگاه دادهٔ عملیاتی اجرا میشود. گزارش فروش سالانهای که سنگین است، فقط کند نیست — قفل و فشار میسازد و ثبت سفارش مشتری را هم کند میکند. جداکردن بار گزارش از بار عملیاتی، با نسخهٔ خواندنی یا جدولهای تجمیعشده، یکی از تصمیمهای معماری است که هرچه دیرتر گرفته شود گرانتر است.
پنجم: کش، ولی نه بهعنوان اولین جواب
کش گذاشتن روی پرسوجویی که ایندکس ندارد، مسئله را پنهان میکند تا لحظهای که کش خالی شود — و آن لحظه معمولاً بدترین لحظهٔ ممکن است، چون کل بار یکجا به پایگاه داده میرسد.
ترتیب درست: اول پرسوجو را درست کنید، بعد اگر هنوز لازم بود کش بگذارید. و مسئلهٔ کهنگی داده را جدی بگیرید — استراتژی کش دربارهٔ همین است.
ششم: مدل داده، که ارزانتر از همه است و دیرتر از همه ممکن
بعضی کندیها با ایندکس حل نمیشوند چون مسئله در مدل است: جدولی که سی ستون اختیاری دارد چون سه موجودیت متفاوت در آن جا شدهاند، یا نرمالسازی افراطی که هر صفحه را به هشت اتصال جدول تبدیل میکند.
اینجا نکتهٔ مرحلهای مهم است: مدل داده در معماری تعیین میشود و بعد از آن تغییرش مهاجرت داده است، نه ویرایش کد. این یکی از دلایلی است که بودجهٔ کارایی باید پیش از ساخت نوشته شود.
اگر هنوز در مرحلهٔ انتخاب هستید، انتخاب پایگاه داده تفاوتهایی را که در این سطح اثر دارند مرور کرده.
ترتیبی که پیشنهاد میکنیم
۱. لاگ پرسوجوی کند را روشن کنید، یک هفته جمع کنید. ۲. بر اساس زمان × تعداد مرتب کنید، پنج ردیف اول را بردارید. ۳. نقشهٔ اجرا را ببینید. معمولاً دو تا از پنج تا با یک ایندکس حل میشوند. ۴. تعداد پرسوجوی هر صفحه را بشمارید و N+1ها را ببندید. ۵. گزارشها را از مسیر عملیاتی جدا کنید. ۶. بعد دربارهٔ کش و سختافزار حرف بزنید.
بیشتر تیمها از بند ششم شروع میکنند. سرور بزرگتر پرسوجوی بدون ایندکس را کمی سریعتر میکند و مسئله را شش ماه به تعویق میاندازد — با هزینهٔ ماهانهای که برنمیگردد.