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 typerows تخمینیتفسیر
پیش از ایندکسALL850000اسکن گسترده جدول
بعد از ایندکس ترکیبیref / range120خواندن بخش محدودتر داده

نکته فنی

این اعداد صرفاً آموزشی هستند و خروجی واقعی دیتابیس شما نیستند. برای تصمیم درست باید توزیع داده، 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);

اصطلاحات مرتبط: بهینه‌سازی کوئری، بی تری، ایندکس بی تری، پلن اجرای کوئری، دیتابیس، زبان پرس‌وجوی ساخت‌یافته.