WIUNIX ACADEMY
پیداکردن کوئریهای پرهزینه در PostgreSQL و خواندن درست plan
هزینهٔ کوئریها را در همان بازهٔ مشکل بسنجید، آمار نامعتبر را کنار بگذارید و روی دادهٔ آزمایشی ببینید تخمین اشتباه تعداد ردیفها چگونه بر تصمیم PostgreSQL اثر میگذارد.
محیطت را انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من3 مقدار قابلتغییر
از اینجا شروع کن
در پایان چه چیزی خواهی داشت؟
با دو نمونهبرداری از pg_stat_statements، کوئریهای پرهزینهٔ یک بازه را پیدا کنید و سپس اختلاف تخمین و اجرای واقعی را در محیط آزمایشی بررسی کنید.
سیستمعاملها و نسخههای پوششدادهشده
مسیرهای مستند برای Ubuntu، Debian و خانوادهٔ Red Hat؛ محصول و کلاینت سازگار باید از قبل نصب باشند. محدودیت هر شاخه در گام نخست آمده است. فرمانها هنگام نگارش روی سرویس واقعی اجرا نشدهاند.
قبل از شروع
- PostgreSQL 18 با pg_stat_statements فعال و نصبشده در schema عمومی همان دیتابیس؛ نقش مشاهده باید اجازهٔ دیدن آمار لازم را داشته باشد.
- دیتابیس دورریختنیِ جداگانه با PostgreSQL 18 و دو service محافظتشدهٔ libpq برای مشاهده و آزمایش.
- فضای موقت و فرصت اجرای مثال صد هزار ردیفی در محیط آزمایش؛ در این مقاله سرویس اصلی restart یا تنظیم سراسری تغییر داده نمیشود.
کدام کوئری در زمان بروز مشکل بیشترین زمان اجرای تجمعی را داشته است؟
اگر کوئریها را بر اساس مجموع زمان از ابتدای کار سرور مرتب کنید، ممکن است مسئلهٔ قدیمی بالای فهرست بماند و عامل کندی امروز دیده نشود. برای بررسی رخداد فعلی، ابتدا و انتهای یک بازه را مشخص میکنیم و اختلاف شمارندهها را میخوانیم.
زمان تجمعی اجرای دیتابیس با تأخیر یک درخواست کاربر فرق دارد. کوئری کوتاهی که بسیار تکرار میشود میتواند در مجموع بیشترین زمانِ سرور را مصرف کند؛ کوئری کمتکرار اما سنگین ممکن است علت کندترین درخواستها باشد. هر دو مهماند، ولی تصمیم یکسانی نمیخواهند.
مشاهده روی سرویس موجود، آزمایش روی دیتابیس جدا
بخش مشاهده فرض میکند pg_stat_statements از قبل روی PostgreSQL 18 فعال و در schema عمومی دیتابیس نصب شده است. برای دنبالکردن این مقاله سرور اصلی را restart یا آمار مشترک را reset نکنید. متن الگوی کوئری حتی پس از حذف مقادیر ثابت میتواند نام اشیای حساس داشته باشد؛ آن را خصوصی نگه دارید.
در بخش دوم، رابطهٔ دو ستون را روی جدول موقت و دادهٔ ساختگی بررسی میکنیم. نتیجهٔ این مثال، اندازهگیری سرعت برنامهٔ شما نیست و مجوز اجرای EXPLAIN ANALYZE روی هر کوئری سرویس اصلی محسوب نمیشود.
دو اتصال متفاوت برای مشاهده و آزمایش انتخاب کنید
یک service موجود برای خواندن آمار و یک service برای دیتابیس دورریختنی لازم است. رمز و TLS در فایل محافظتشدهٔ اتصال میمانند. در فرم فقط نام serviceها و تعداد ردیف آزمایشی را وارد کنید؛ پارامتر واقعی کوئری مشتری را اینجا نگذارید.
مقدارهای فرم در همین تب نگهداری میشوند. پس از «اعمال»، متن و پنلها با هم عوض میشوند؛ تا وقتی تغییر نامعتبر یا اعمالنشده دارید، کپی متوقف میماند. پیش از اجرا، مقصد هر دو service را جداگانه تأیید کنید.
قدم بعدی
پیش از شروع، مسیر ابزار و محل اجرای فرمانها را بررسی کنید
سرور باید از قبل PostgreSQL نسخهٔ ۱۸ باشد و افزونهٔ pg_stat_statements در آن بارگذاری و در schema موردنظر نصب شده باشد. انتخاب سیستمعامل در این صفحه مربوط به کلاینت مدیریت است و افزونهای روی سرور فعال نمیکند. در Ubuntu نسخههای ۲۶٫۱۰ و ۲۶٫۰۴ و Debian نسخههای ۱۳ و ۱۲، باینریهای کلاینت PGDG در /usr/lib/postgresql/18/bin قرار دارند. در RHEL، Rocky Linux و AlmaLinux شاخههای ۹ و ۱۰، مسیر /usr/pgsql-18/bin به کار میرود؛ فرمانهای این شاخه مسیر کامل psql را دارند تا کلاینت قدیمیترِ توزیع اشتباهی اجرا نشود. اتصال پایش و اتصال آزمایشگاه را جدا نگه دارید. فایلهای محافظتشدهٔ libpq متعلق به حساب اجراکنندهٔ کلاینتاند؛ تنظیمات سرور را برای یکسانکردن مسیرها بین توزیعها جابهجا نکنید.
این مسیرها از مستندات استخراج شدهاند و آزمون عملی سازگاری محسوب نمیشوند. ابتدا /etc/os-release و نسخهٔ دقیق محصول را بررسی کنید. حسابها، دسترسی شبکه و اعتبارنامههای محافظتشده باید از قبل آماده باشند. برای آمادهکردن ابزارها، سرویس موجود را دوباره راهاندازی نکنید، دیتابیس تازه مقداردهی اولیه نکنید، پورتی روی فایروال باز نکنید و Python سیستم را تغییر ندهید.
کلاینت مدیریت مجاز؛ بررسیهای مخصوص گره فقط روی همان گرهٔ موجود
cat /etc/os-release
id
test -x /usr/lib/postgresql/18/bin/psql
/usr/lib/postgresql/18/bin/psql --versionسیستمعامل، مسیر و نسخهٔ ابزار با محیط انتخابی سازگار است؛ در صورت تفاوت، پیش از تغییر داده توقف کنید.
قدم بعدی
نشست مشاهده را تا پایان نمونهبرداری باز نگه دارید
از ایستگاه مدیریت به دیتابیس موردنظر وصل شوید. پنلهای SQL بخش مشاهده باید در همین اتصال اجرا شوند، چون نمونهٔ اول در جدول موقت این نشست ذخیره میشود. autocommit را روشن نگه دارید؛ پیچیدن همهٔ مراحل در یک تراکنش طولانی میتواند تصویر آمار را ثابت نگه دارد.
اگر افزونه موجود نیست یا جای دیگری نصب شده، از رویهٔ همان محیط استفاده کنید؛ نبودن آن را با نصب یا restart بدون برنامه جبران نکنید.
رایانهٔ مدیریت پایگاهداده
/usr/lib/postgresql/18/bin/psql -X -v ON_ERROR_STOP=1 'service=academy_stats'یک اتصال پیوسته برای خواندن آمار باز است و مقصد آن را میشناسید.
قدم بعدی
نمونهٔ اول را بدون دستزدن به آمار مشترک بگیرید
هویت کامل هر رکورد از database، user، queryid و toplevel تشکیل میشود؛ queryid بهتنهایی کافی نیست. همراه شمارندهها، زمان آغاز آمار همان رکورد و وضعیت reset و dealloc را هم ذخیره میکنیم تا بعداً دو چیز نامربوط را از هم کم نکنیم.
پس از گرفتن نمونه، در prompt منتظر بازهای بمانید که بار مورد بررسی واقعاً در آن جریان دارد. این مقاله برای سرویس اصلی بار مصنوعی تولید نمیکند. زمان شروع و پایان را در یادداشت رخداد نگه دارید.
همان نشست باز psql برای پایش
SELECT version(), current_database();
SELECT extversion FROM pg_extension WHERE extname='pg_stat_statements' AND extnamespace='public'::regnamespace;
CREATE TEMP TABLE academy_info_before AS SELECT clock_timestamp() AS captured_at, stats_reset, dealloc FROM public.pg_stat_statements_info;
CREATE TEMP TABLE academy_stat_before AS SELECT dbid,userid,queryid,toplevel,stats_since,calls,total_exec_time,rows,shared_blks_read,temp_blks_written FROM public.pg_stat_statements WHERE dbid=(SELECT oid FROM pg_database WHERE datname=current_database());
\prompt 'Wait for the representative interval, then press Enter: ' interval_doneنمونهٔ اول در همین نشست ذخیره شده و شمارندههای مشترک تغییر نکردهاند.