تشخیص فولاسکن جدول تو SQLite بدون EXPLAIN
خلاصهٔ کاملتر
ماجرا از پست مهاجرت lobste.rs به SQLite شروع میشه. یه جمله از اون پست توجه آرون پترسون رو جلب کرده: «کاش میشد تو تست بگیم اگه به فولاسکن جدول برخوردی، تست رو رد کن» — چیزی که به گفتهٔ نویسندهٔ اون پست، مشکلات کارایی اولین استقرارشون رو میگرفت.
نویسنده میگه SQLite دقیقاً برای همین یه چیزی داره: برای هر عبارت آمادهشده آمار جمع میکنه و از طریق API در اختیار میذاره. نتیجهاش اینه که بعد از اجرای عبارت، بدون اینکه لازم باشه EXPLAIN بزنی یا پلن اجرا رو تفسیر کنی، میشه فهمید اون کوئری فولاسکن کرده یا نه.
شکل کار تو Ruby اینجوریه: بعد از اجرای عبارت، مقدار fullscan_steps رو میخونی و اگه از صفر بیشتر بود یعنی کل جدول پیموده شده.
stmt = db.prepare("SELECT * FROM users WHERE age = ?")
stmt.bind_param(1, 42)
stmt.to_a
fullscan_steps = stmt.stat(:fullscan_steps)
if fullscan_steps > 0
puts "=> query performed a full table scan"
endتو نمونهٔ کامل پست، همین کوئری روی یه جدول هزارردیفی اول عدد بزرگی برمیگردونه، بعد با ساختن ایندکس روی ستون age و اجرای دوبارهٔ همون کوئری، شمارنده میره سراغ صفر. یعنی همین یه عدد کافیه که بفهمی ایندکست گرفته یا نه.
نویسنده در آخر یه پیشنهاد باز میذاره: به نظرش میشه این رو تو Rails آورد و موقع تست و توسعه هشدار داد یا حتی استثنا انداخت. دربارهٔ اینکه تو محیط عملیاتی هم همیشه چک بشه مطمئن نیست، ولی میگه شاید اشکالی نداشته باشه.
نکات کلیدی:
- SQLite برای هر عبارت آمادهشده آمار اجرا نگه میداره
- شمارندهٔ fullscan_steps بعد از اجرا میگه کل جدول پیموده شده یا نه
- نیازی به EXPLAIN یا تفسیر پلن اجرا نیست
- بعد از ساختن ایندکس مناسب، شمارنده صفر میشه
- ایدهٔ پیشنهادی: هشدار یا خطا در تست و توسعهٔ Rails




