تا حالا شده یه اپلیکیشن پایتونی خفن بنویسید که تو پردازش‌های عادی مثل موشک کار کنه، اما همین که کارش به دیتابیس می‌افته، انگار پاش میره روی ترمز؟ اینجاست که معمولاً همه انگشت اتهام رو سمت دیتابیس میگیرن. اما واقعیت اینه که خیلی وقت‌ها مشکل از خود دیتابیس نیست، بلکه مشکل از «زبان مشترک» یا همون درایوریه که کد ما رو به دیتابیس وصل میکنه.

اگر از پایتون و دیتابیس قدرتمند PostgreSQL استفاده میکنید و دنبال این هستید که اپلیکیشنتون زیر بار ترافیک سنگین آخ نگه، احتمالاً اسم asyncpg به گوشتون خورده. تو این مقاله می‌خوایم به زبون ساده بررسی کنیم که چرا این کتابخونه، دیوار صوتی سرعت رو تو دنیای پایتون شکسته.

asyncpg چیه؟

کتابخونه asyncpg یک درایور (Driver) دیتابیس برای پایتونه که مخصوص فریمورک asyncio و دیتابیس PostgreSQL طراحی شده. وظیفه‌اش چیه؟ اینه که درخواست‌های (Queries) شما رو بگیره، ببره سمت دیتابیس، و جواب رو برگردونه. اما کاری که بقیه درایورها با یه ماشین معمولی انجام می‌دن رو، asyncpg با یه ماشین فرمول یک انجام می‌ده!

طبق بنچمارک‌ها، asyncpg به طور میانگین ۳ تا ۵ برابر سریع‌تر از درایورهای استانداردی مثل psycopg2 (حتی با aiopg) عمل می‌کنه. اما راز این سرعت دیوانه‌وار چیه؟

رازهای پشت پرده سرعت asyncpg

سرعت فوق‌العاده‌ی این کتابخونه جادو نیست، بلکه نتیجه‌ی چند تا تصمیم مهندسی به‌شدت هوشمندانه‌ است:

۱. صحبت کردن به زبان مادری (پروتکل باینری)

بیشتر درایورهای دیتابیس، برای ارتباط با Postgres از پروتکل‌های متنی (Text) استفاده می‌کنن. یعنی مثلاً اگر می‌خواید عدد 12345 رو بفرستید، اون رو تبدیل به متن می‌کنن، می‌فرستن، و دیتابیس دوباره اون رو به عدد تبدیل می‌کنه.

اما asyncpg مستقیم از پروتکل باینری (Binary Protocol) خود Postgres استفاده می‌کنه. یعنی داده‌ها رو دقیقاً با همون ساختار صفرویکی که پردازنده می‌فهمه جابه‌جا می‌کنه. این کار، بار پردازشی (Overhead) تبدیل فرمت‌ها رو به صفر می‌رسونه.

۲. قلب تپنده‌ای از جنس C (استفاده از Cython)

اگرچه شما کد پایتون می‌نویسید، اما موتور زیر کاپوت asyncpg با Cython نوشته شده. کدهای Cython مستقیماً به زبان C کامپایل می‌شن. در نتیجه، بخش‌های سنگین و محاسباتی درایور با سرعت خارق‌العاده‌ی C اجرا می‌شن و محدودیت‌های سرعت پایتون رو دور می‌زنن.

۳. کش کردن هوشمند کوئری‌ها (Prepared Statements)

وقتی شما یه کوئری به دیتابیس می‌فرستید، دیتابیس باید اول اون رو تحلیل (Parse) کنه، بهترین راه اجراش رو پیدا کنه و بعد اجراش کنه. asyncpg به صورت خودکار از قابلیتی به اسم Prepared Statements استفاده می‌کنه. یعنی اگر یه کوئری رو چند بار اجرا کنید، دیتابیس ساختار اون رو تو حافظه‌اش نگه می‌داره (کش می‌کنه) و دفعات بعدی فقط مقادیر جدید رو بهش تزریق می‌کنه. این کار سرعت اجرای کوئری‌های تکراری رو به شدت بالا می‌بره.

۴. ذات Asynchronous (غیرهم‌زمان)

همونطور که از اسمش پیداست، asyncpg از پایه برای برنامه‌نویسی ناهمگام (Async) طراحی شده. تو مدل‌های سنتی، وقتی درایور درخواستی رو به دیتابیس می‌ده، کل برنامه قفل می‌شه (Block) تا جواب برگرده. اما اینجا وقتی درخواستی فرستاده می‌شه، پایتون می‌ره سراغ بقیه کارهاش و هر وقت دیتابیس جواب داد، برمی‌گرده سراغش. این یعنی استفاده‌ی ۱۰۰ درصدی از منابع سرور بدون هدر دادن زمان.

کِی باید از asyncpg استفاده کنیم؟

اگر شرایط زیر رو دارید، استفاده از این کتابخونه براتون لازمه:

  • فریمورک‌های مدرن: از فریمورک‌های غیرهمزمان پایتون مثل FastAPI، Sanic، Starlette یا Aiohttp استفاده می‌کنید.

  • ترافیک بالا: اپلیکیشن شما باید هزاران درخواست در ثانیه رو هندل کنه و میلی‌ثانیه‌ها براتون مهمن.

  • نیاز به ابزار سطح پایین (Low-level): می‌خواید کوئری‌های SQL رو خودتون بنویسید و دوست ندارید لایه‌های اضافه سرعتتون رو کم کنن.

نکته مهم: اگر از ORM هایی مثل SQLAlchemy استفاده می‌کنید، خبر خوب اینه که نسخه‌های جدید SQLAlchemy (از 1.4 به بعد) به صورت کامل از asyncpg به عنوان موتور زیرین پشتیبانی میکنن. یعنی می‌تونید هم راحتی ORM رو داشته باشید و هم سرعت asyncpg رو!

کِی سراغش نریم؟

هیچ ابزاری برای همه شرایط بی‌نقص نیست. تو این حالت‌ها بهتره از همون psycopg2 یا psycopg3 استفاده کنید:

  • اپلیکیشنتون Sync هست (مثلاً از نسخه‌های قدیمی جانگو یا فلسک استفاده می‌کنید).

  • ترافیک اپلیکیشن اونقدر پایینه که پیچیدگی اضافه کردن کدهای async/await اصلاً توجیهی نداره.

جمع بندی

اگر تو دنیای وب پایتون کار می‌کنید و دیتابیس محبوبتون PostgreSQL هست، یاد گرفتن و استفاده از asyncpg یکی از اون مهارت‌هاییه که شما رو از یه برنامه‌نویس معمولی به یه برنامه‌نویس ارشد (Senior) که دغدغه‌ی پرفورمنس داره تبدیل می‌کنه. پس کمربندها رو ببندید و اجازه بدید اپلیکیشنتون با سرعت نور به دیتابیس وصل بشه!