Database Index یا ایندکس در دیتابیس ساختار کمکی برای سریعتر پیدا کردن رکوردهاست. بدون ایندکس، کوئری ممکن است تمام جدول را پیمایش کند. ایندکس هزینه دارد، فضای ذخیرهسازی مصرف میکند و عملیات درج، حذف و ویرایش را نیز میتواند کندتر کند.
مثال واقعی و استفاده از EXPLAIN
-- A typical slow lookup in an orders table
EXPLAIN SELECT id, total FROM orders
WHERE customer_id = 42 AND status = 'paid'
ORDER BY created_at DESC LIMIT 20;
CREATE INDEX idx_orders_customer_status_created
ON orders (customer_id, status, created_at);
EXPLAIN SELECT id, total FROM orders
WHERE customer_id = 42 AND status = 'paid'
ORDER BY created_at DESC LIMIT 20;
در MySQL ستونهای key، type، rows و Extra سرنخ میدهند که چه ایندکسی به کار رفته است. در PostgreSQL میتوان از EXPLAIN (ANALYZE, BUFFERS) برای مشاهده زمان واقعی و I/O استفاده کرد. دستورهای ANALYZE واقعا کوئری را اجرا میکنند و روی کوئریهای تغییردهنده داده باید با احتیاط به کار روند.
| وضعیت فرضی | access type | rows تخمینی | تفسیر |
|---|---|---|---|
| پیش از ایندکس | ALL | 850000 | اسکن گسترده جدول |
| بعد از ایندکس ترکیبی | ref / range | 120 | خواندن بخش محدودتر داده |
نکته فنی
این اعداد صرفاً آموزشی هستند و خروجی واقعی دیتابیس شما نیستند. برای تصمیم درست باید توزیع داده، Selectivity و هزینه درج و بهروزرسانی را هم سنجید.
انواع ایندکس
| نوع ایندکس | مناسب برای | محدودیت |
|---|---|---|
| B-tree / B+ tree | برابری، بازه و مرتبسازی | انتخاب ترتیب ستون اهمیت دارد |
| Hash | برابری دقیق در موتورهای پشتیبانیشده | معمولاً مناسب جستوجوی بازه نیست |
| Unique | جلوگیری از مقدار تکراری در کلید | باید قوانین NULL و Collation را شناخت |
| Composite | فیلتر چندستونی | قواعد پیشوند چپ در بسیاری از موتورها |
| Full-text | جستوجوی متنی | برای همه الگوهای LIKE جایگزین نیست |
| GIN / GiST | آرایه، JSONB و داده مکانی در PostgreSQL | هزینه و رفتار به نوع اپراتور وابسته است |
| BRIN | جدولهای بسیار بزرگ با داده فیزیکی همبسته | برای توزیع پراکنده کمتر مفید است |
| Partial / Filtered | زیرمجموعه پرتکرار داده | بسته به دیتابیس پشتیبانی متفاوت دارد |
B-tree با Hash Index چه تفاوتی دارد؟
بی تری ساختار کلیدها را مرتب نگه میدارد و برای بازه و مرتبسازی مفید است. Hash Index نگاشت مبتنی بر هش را برای برابری سریع فراهم میکند، ولی برای ORDER BY و شروط بازه عموماً مناسب نیست.
-- PostgreSQL partial index
CREATE INDEX idx_orders_unpaid ON orders(created_at)
WHERE status = 'unpaid';
-- MySQL: normal composite index
CREATE INDEX idx_orders_status_time ON orders(status, created_at);
اصطلاحات مرتبط: بهینهسازی کوئری، بی تری، ایندکس بی تری، پلن اجرای کوئری، دیتابیس، زبان پرسوجوی ساختیافته.