Query Optimization یا بهینهسازی کوئری مجموعه روشهای بهبود زمان پاسخ و مصرف منابع یک کوئری دیتابیس است. اولین قدم بهینهسازی، اندازهگیری است نه افزودن تصادفی ایندکس.
مثال فروشگاه: سفارشهای اخیر یک مشتری
-- Initial query on a large table
SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC;
-- Targeted projection and pagination
SELECT id, total, created_at FROM orders
WHERE customer_id = 42
ORDER BY created_at DESC LIMIT 20;
CREATE INDEX idx_orders_customer_time ON orders(customer_id, created_at);
مقایسه پلن اجرای کوئری
| موتور | دستور مشاهده پلن | چه چیزی را بررسی کنیم؟ |
|---|---|---|
| MySQL | EXPLAIN SELECT ... | type، key، rows، Extra |
| MySQL 8.4 | EXPLAIN ANALYZE SELECT ... | تخمین در مقابل اجرای واقعی و زمان |
| PostgreSQL | EXPLAIN SELECT ... | Seq Scan، Index Scan و Join Plan |
| PostgreSQL | EXPLAIN (ANALYZE, BUFFERS) SELECT ... | زمان واقعی، buffer hit/read و تعداد حلقهها |
نمونه فرضی خروجی و تحلیل
| مرحله | عملیات | تعداد سطر تخمینی | زمان فرضی |
|---|---|---|---|
| قبل | Seq Scan / ALL | 1,200,000 | 740ms |
| بعد از محدود کردن ستونها و ایندکس | Index Scan / range | 20 | 12ms |
این اعداد برای آموزش فرض شدهاند و خروجی اندازهگیری واقعی نیستند. در عمل باید اثر کش گرم، اندازه جدول، نوع سختافزار و زمان شبکه نیز کنترل شود. در PostgreSQL ممکن است برای جدول کوچک، Seq Scan کاملاً بهینه باشد.
روشهای دیگر
- جلوگیری از N+1 با ایگر لودینگ مناسب
- بهجای OFFSET بزرگ، استفاده از Keyset Pagination در شرایط مناسب
- انتخاب ستونهای لازم به جای SELECT *
- ایندکس ترکیبی متناسب با WHERE و ORDER BY
- کنترل بازه تراکنش و تعداد اتصالهای همزمان
- استفاده از Materialized View یا Cache برای پرسوجوهای سنگین و تکراری
نکته فنی
ایندکس اضافی، هزینه Write و مصرف دیسک را افزایش میدهد. پلن را پس از تغییر اندازهگیری کنید و ایندکس بدون استفاده را شناسایی کنید.
اصطلاحات مرتبط: ایندکسینگ، بی تری، پلن اجرای کوئری، مشکل کوئری N+1، ایگر لودینگ، کانکشن پولینگ، نمای مادیشده.