Database Scoped Performance Configuration در SQL Server | راهنمای جامع

راهنمای جامع تنظیمات Performance در سطح پایگاه داده SQL Server

توسط admin | گروه SQL Server | 1405/05/01

نظرات 0

راهنمای جامع تنظیمات Performance در سطح پایگاه داده SQL Server

Database Scoped Configuration یکی از مهم‌ترین ابزارهای SQL Server برای جداکردن سیاست‌های عملکردی یک Database از تنظیمات سراسری Instance است. وقتی یک سرور هم‌زمان OLTP، گزارش‌گیری، Data Warehouse یا نرم‌افزار قدیمی مهاجرت‌شده را میزبانی می‌کند، یک سیاست واحد برای همه بارها همیشه منطقی نیست.

این مجموعه روی ۱۷ تنظیمی تمرکز دارد که با Query Optimizer، Cardinality Estimation، Parallelism، Memory Grant، Intelligent Query Processing، Query Store و Plan Cache درگیرند. هر گزینه مقاله مستقل دارد تا تصمیم Production به چند خط توضیح و یک Toggle ساده محدود نشود.

اصل مشترک همه این موضوع‌ها این است: Feature خوب لزوماً برای هر Workload خوب نیست. نسخه Engine، Compatibility Level، شکل داده، Query Plan و هم‌زمانی تعیین می‌کنند که نتیجه واقعی چه باشد. بنابراین Baseline، تغییر کوچک، اندازه‌گیری و Rollback چهار ستون تصمیم هستند.

دسترسی سریع به مقاله‌های تخصصی

نقشه ذهنی تنظیمات Performance

برای فهم بهتر، این گزینه‌ها را در چند خانواده ببینید: Parallelism، Cardinality و Optimizer، Memory Grant Feedback، Adaptive Execution، Plan Feedback و Plan Cache. این دسته‌بندی کمک می‌کند به‌جای روشن‌کردن تصادفی Featureها، اول لایه مشکل را پیدا کنید.

DATABASE SCOPED PERFORMANCE - نمودار فنی 1نقشه معماری DATABASE SCOPED PERFORMANCE و اجزای مرتبط در SQL ServerDATABASE SCOPED PERFORMANCEMAXDOPMemory GrantAdaptive JoinUDF InliningCE/DOP FeedbackQuery StoreMAXDOPMemory GrantAdaptive JoinUDF Inlining

در این معماری، Optimizer و Query Store نقش پل را دارند. بعضی قابلیت‌ها هنگام Compile تصمیم می‌گیرند، بعضی در Runtime بازخورد می‌گیرند و بعضی تجربه اجرا را برای دفعات بعد نگه می‌دارند. به همین دلیل مشاهده Plan واقعی و Runtime هم‌زمان ضروری است.

Parallelism و ظرفیت CPU

MAXDOP سیاست پایه موازی‌سازی را محدود می‌کند و DOP Feedback از رفتار Queryهای تکراری برای تنظیم بهتر DOP کمک می‌گیرد. اولی Policy است و دومی Feedback؛ جای هم را نمی‌گیرند.

تنظیم MAXDOP در سطح پایگاه داده

در سروری که چند Database با بارهای متفاوت دارد، MAXDOP دیتابیس‌محور اجازه می‌دهد OLTP و بار تحلیلی سیاست یکسانی نداشته باشند. مقدار صفر به رفتار سطح سرور برمی‌گردد و Query Hint همچنان می‌تواند برای Statement خاص اولویت داشته باشد. مطالعه آموزش کامل MAXDOP با مثال‌های عملی

DOP Feedback در SQL Server

DOP Feedback رفتار Queryهای تکراری را مشاهده می‌کند و در صورت تشخیص موازی‌سازی نامناسب می‌تواند DOP مؤثر را در اجراهای بعدی تنظیم کند. هدف تعادل سرعت تک Query و Throughput کل است. مطالعه آموزش کامل DOP_FEEDBACK با مثال‌های عملی

Cardinality و رفتار Optimizer

این گروه روی تخمین تعداد ردیف، مقدار پارامتر هنگام Compile، اصلاحات Optimizer و بازخورد CE تمرکز دارد. Statistics و Data Skew همیشه باید قبل از تغییر بررسی شوند.

مدیریت Legacy Cardinality Estimation

Cardinality Estimator تعداد ردیف‌های احتمالی را پیش‌بینی می‌کند و این تخمین روی Join، Memory Grant و Index Access اثر دارد. Legacy CE بیشتر ابزار سازگاری و عیب‌یابی است تا گزینه‌ای که بدون تحلیل دائماً روشن بماند. مطالعه آموزش کامل LEGACY_CARDINALITY_ESTIMATION با مثال‌های عملی

کنترل Parameter Sniffing در SQL Server

Parameter Sniffing معمولاً مفید است چون Plan را با مقدار واقعی Compile می‌کند، اما در داده‌های بسیار نامتوازن یک Plan ذخیره‌شده ممکن است نماینده همه پارامترها نباشد. خاموش‌کردن سراسری باید آخرین انتخاب باشد. مطالعه آموزش کامل PARAMETER_SNIFFING با مثال‌های عملی

فعال‌سازی Query Optimizer Hotfixes

این گزینه راهی برای فعال‌کردن مجموعه اصلاحات Optimizer در سطح Database است و برای Rollout مرحله‌ای تغییر رفتار پس از CU مفید است. باید با Regression Test و Query Store همراه شود. مطالعه آموزش کامل QUERY_OPTIMIZER_HOTFIXES با مثال‌های عملی

Cardinality Estimation Feedback

CE Feedback وقتی بعضی فرض‌های مدل تخمین باعث خطای پایدار می‌شوند، می‌تواند رفتار مناسب‌تری برای اجراهای بعدی اعمال کند و از Plan Feedback کمک بگیرد. مطالعه آموزش کامل CE_FEEDBACK با مثال‌های عملی

Memory Grant و پایداری حافظه

Grant زیاد حافظه را اشغال و Grant کم Spill ایجاد می‌کند. Feedback، Persistence و Percentile برای Queryهای تکرارشونده تلاش می‌کنند این تعادل را بهتر کنند.

کنترل Batch Mode Memory Grant Feedback

Grant بیش‌ازحد حافظه را بی‌دلیل رزرو می‌کند و Grant کم Spill به tempdb می‌سازد. Feedback در Batch Mode برای Queryهای تکرارشونده تلاش می‌کند اندازه Grant را متعادل کند. مطالعه آموزش کامل BATCH_MODE_MEMORY_GRANT_FEEDBACK با مثال‌های عملی

کنترل Row Mode Memory Grant Feedback

Row Mode Memory Grant Feedback دامنه اصلاح Grant را به Queryهای Row Mode گسترش می‌دهد و برای Sort و Hashهای تکراری با Grant نامناسب کاربرد دارد. مطالعه آموزش کامل ROW_MODE_MEMORY_GRANT_FEEDBACK با مثال‌های عملی

ماندگاری Memory Grant Feedback

بدون Persistence، Feedback می‌تواند به عمر Plan در Cache وابسته باشد. با ماندگارشدن، تجربه اجرا از طریق Query Store حفظ می‌شود و بعد از Restart سریع‌تر قابل استفاده است. مطالعه آموزش کامل MEMORY_GRANT_FEEDBACK_PERSISTENCE با مثال‌های عملی

Percentile Memory Grant Feedback

در Queryهایی که مصرف حافظه بین اجراها تغییر می‌کند، نگاه به مجموعه اجراهای قبلی می‌تواند Grant باثبات‌تری بسازد و رفتار رفت‌وبرگشتی را کمتر کند. مطالعه آموزش کامل MEMORY_GRANT_FEEDBACK_PERCENTILE_GRANT با مثال‌های عملی

Adaptive و Intelligent Query Processing

این قابلیت‌ها محدودیت برخی تصمیم‌های Compile سنتی را با Runtime Decision، Inlining یا Compilation دیرتر کاهش می‌دهند. هر Feature شرایط واجد صلاحیت خودش را دارد.

کنترل Batch Mode Adaptive Joins

Adaptive Join بخشی از تصمیم Join را از Compile به Runtime منتقل می‌کند. Plan یک آستانه دارد و بعد از روشن‌شدن اندازه واقعی ورودی، مسیر مناسب‌تر انتخاب می‌شود. مطالعه آموزش کامل BATCH_MODE_ADAPTIVE_JOINS با مثال‌های عملی

Batch Mode on Rowstore

Batch Mode می‌تواند پردازش دسته‌ای را کارآمدتر کند و برای برخی Queryهای تحلیلی Rowstore مصرف CPU را کاهش دهد. روشن بودن گزینه تضمین نمی‌کند هر Query Batch Mode شود. مطالعه آموزش کامل BATCH_MODE_ON_ROWSTORE با مثال‌های عملی

Scalar UDF Inlining در T-SQL

Scalar UDF سنتی می‌تواند هزینه واقعی خود را از Optimizer پنهان کند. Inlining در شرایط واجد صلاحیت منطق تابع را وارد Plan اصلی می‌کند تا Optimizer دید بهتری داشته باشد. مطالعه آموزش کامل TSQL_SCALAR_UDF_INLINING با مثال‌های عملی

Interleaved Execution برای Multi-Statement TVF

MSTVFها historically می‌توانند با تخمین ثابت Plan نامناسب بسازند. Interleaved Execution Optimization را موقتاً متوقف می‌کند، نتیجه TVF را می‌بیند و ادامه Plan را با تخمین واقع‌بینانه‌تری می‌سازد. مطالعه آموزش کامل INTERLEAVED_EXECUTION_TVF با مثال‌های عملی

Deferred Compilation برای Table Variable

Table Variableها historically با تخمین‌های ساده می‌توانستند Plan ضعیف بسازند. Deferred Compilation زمان Compile را عقب می‌اندازد تا Optimizer تعداد ردیف واقعی‌تری ببیند. مطالعه آموزش کامل DEFERRED_COMPILATION_TV با مثال‌های عملی

Plan Stability و Cache

Optimized Plan Forcing با مسیر بازتولید Forced Plan در Query Store مرتبط است، در حالی که Clear Procedure Cache ابزار عملیاتی برای حذف Planهای Cache‌شده است. یکی را نباید درمان دیگری دانست.

Optimized Plan Forcing

Plan Forcing برای ثبات مهم است، اما بازتولید Plan اجباری می‌تواند هزینه Optimization داشته باشد. Optimized Plan Forcing برای بعضی Planها Replay Script نگه می‌دارد تا مسیر تولید دوباره کوتاه‌تر شود. مطالعه آموزش کامل OPTIMIZED_PLAN_FORCING با مثال‌های عملی

پاک‌سازی Procedure Cache در سطح پایگاه داده

Clear کردن Procedure Cache برای تست کنترل‌شده یا خروج از Plan نامناسب مفید است، اما عملیات روزمره بی‌خطر نیست. بعد از آن Queryها دوباره Compile می‌شوند و CPU یا Latency موقتاً بالا می‌رود. مطالعه آموزش کامل CLEAR_PROCEDURE_CACHE با مثال‌های عملی

جدول مقایسه سریع

تنظیمکاربرد اصلیمقدار یا نکتهلینک آموزش کامل
MAXDOPکنترل حداکثر درجه موازی‌سازی Queryهای یک Database بدون دست‌زدن به سیاست سراسری Instance0 یا عدد صحیح متناسب با سیاست موازی‌سازیآموزش کامل
LEGACY_CARDINALITY_ESTIMATIONانتخاب مدل قدیمی تخمین Cardinality برای Query Optimizer در سطح یک DatabaseON یا OFFآموزش کامل
PARAMETER_SNIFFINGکنترل استفاده Optimizer از مقدار پارامتر زمان Compile برای ساخت Plan در سطح DatabaseON یا OFFآموزش کامل
QUERY_OPTIMIZER_HOTFIXESکنترل استفاده از اصلاحات Query Optimizer که خارج از رفتار پایه Compatibility Level ارائه شده‌اندON یا OFFآموزش کامل
BATCH_MODE_MEMORY_GRANT_FEEDBACKاصلاح تدریجی Memory Grant Queryهای Batch Mode با استفاده از تجربه اجراهای قبلیON یا OFFآموزش کامل
ROW_MODE_MEMORY_GRANT_FEEDBACKتنظیم تطبیقی Memory Grant برای Queryهایی که در Row Mode اجرا می‌شوندON یا OFFآموزش کامل
MEMORY_GRANT_FEEDBACK_PERSISTENCEذخیره Feedback مربوط به Memory Grant با کمک Query Store تا تجربه تنظیم‌شده پس از Eviction یا Restart از بین نرودON یا OFFآموزش کامل
MEMORY_GRANT_FEEDBACK_PERCENTILE_GRANTمحاسبه Memory Grant بر اساس توزیع اجراهای قبلی به‌جای تکیه ساده بر آخرین اجراON یا OFFآموزش کامل
BATCH_MODE_ADAPTIVE_JOINSانتخاب پویا بین Nested Loops و Hash Join در Runtime بر اساس تعداد واقعی ردیف‌هاON یا OFFآموزش کامل
BATCH_MODE_ON_ROWSTOREامکان استفاده از Batch Mode برای برخی Queryهای تحلیلی روی جداول Rowstore بدون الزام ColumnstoreON یا OFFآموزش کامل
TSQL_SCALAR_UDF_INLININGتبدیل برخی Scalar UDFهای واجد شرایط به عبارت Relational داخل Query برای حذف سربار فراخوانی ردیف‌به‌ردیفON یا OFFآموزش کامل
INTERLEAVED_EXECUTION_TVFبهبود تخمین Cardinality برای MSTVF با مکث در Optimization و استفاده از نتیجه واقعی میانیON یا OFFآموزش کامل
DEFERRED_COMPILATION_TVبه‌تعویق‌انداختن Compile تا پس از پرشدن Table Variable برای استفاده از Cardinality واقعی‌تر در اولین CompileON یا OFFآموزش کامل
DOP_FEEDBACKتنظیم بازخوردی درجه موازی‌سازی Queryهای تکرارشونده برای کاهش Parallelism نامناسب و بهبود بهره‌وری منابعON یا OFFآموزش کامل
CE_FEEDBACKاستفاده از Feedback برای اصلاح برخی فرض‌های Cardinality Estimation در Queryهای تکرارشوندهON یا OFFآموزش کامل
OPTIMIZED_PLAN_FORCINGکاهش سربار Compilation هنگام Plan Forcing با ذخیره و استفاده از Optimization Replay Script در شرایط واجد صلاحیتON یا OFFآموزش کامل
CLEAR_PROCEDURE_CACHEحذف Planهای Cache‌شده یک Database یا در نسخه‌های پشتیبانی‌شده یک Plan مشخص برای Compilation مجدددستور اجرایی؛ ON/OFF نداردآموزش کامل

روش استاندارد تغییر در Production

یک Change حرفه‌ای با Command شروع نمی‌شود؛ با فرضیه شروع می‌شود. «Query گزارش فروش به دلیل Memory Grant کم Spill می‌کند» قابل سنجش است، اما «SQL کند است، چند Feature را ON کنیم» فرضیه نیست. در حالت دوم حتی اگر سیستم بهتر شود، علت بهبود معلوم نیست.

  1. مسئله را با Query ID، زمان رخداد و Metric تعریف کنید.
  2. Baseline را از Query Store، Execution Plan و DMV مرتبط ثبت کنید.
  3. نسخه Engine و Compatibility Level را بررسی کنید.
  4. فقط یک تغییر را در هر آزمایش اعمال کنید.
  5. چند اجرای قابل مقایسه بسنجید.
  6. اثر تک Query و کل Workload را جدا تحلیل کنید.
  7. در Regression فوراً Rollback و سپس Root Cause Analysis کنید.
DATABASE SCOPED PERFORMANCE - نمودار فنی 2جریان اجرای DATABASE SCOPED PERFORMANCE از پیکربندی تا RuntimeDATABASE SCOPED PERFORMANCEALTERMAXDOPOptimizerAdaptive JoinRuntimeCE/DOP FeedbackQuery StoreMAXDOPMemory GrantAdaptive JoinUDF Inlining

جریان استاندارد از Baseline به Change، Compile یا Runtime و سپس Measure می‌رود. حذف هر مرحله، تصمیم را از مهندسی به حدس نزدیک می‌کند.

۶ مثال عملی ترکیبی

مثال 1: خواندن همه Database Scoped Configurationها

قبل از هر تغییر Snapshot کامل تنظیمات را نگه دارید.

SELECT name, value, value_for_secondary
FROM sys.database_scoped_configurations
ORDER BY name;
تنظیمنمونه مقدار
MAXDOP0
PARAMETER_SNIFFING1

خروجی صرفاً نمونه شکل نتیجه است؛ مقدار واقعی را از محیط خودتان با Timestamp در Baseline ثبت کنید.

مثال 2: تنظیم MAXDOP برای همین Database

برای Workload متفاوت، دامنه Database از تغییر سراسری دقیق‌تر است.

ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 4;
نتیجهمعنا
Command completedسیاست Database اعمال شد

خروجی صرفاً نمونه شکل نتیجه است؛ مقدار واقعی را از محیط خودتان با Timestamp در Baseline ثبت کنید.

مثال 3: بررسی وضعیت Query Store

Query Store برای تاریخچه Plan و برخی Feedbackهای جدید اهمیت دارد.

SELECT desired_state_desc, actual_state_desc, readonly_reason
FROM sys.database_query_store_options;
desired_state_descactual_state_desc
READ_WRITEREAD_WRITE

خروجی صرفاً نمونه شکل نتیجه است؛ مقدار واقعی را از محیط خودتان با Timestamp در Baseline ثبت کنید.

مثال 4: بررسی Compatibility Level

بسیاری از Featureهای IQP به سطح سازگاری وابسته‌اند.

SELECT name, compatibility_level
FROM sys.databases
WHERE database_id = DB_ID();
Databasecompatibility_level
CurrentDatabase160

خروجی صرفاً نمونه شکل نتیجه است؛ مقدار واقعی را از محیط خودتان با Timestamp در Baseline ثبت کنید.

مثال 5: پایش Memory Grantهای فعال

Grant را کنار Spill و Concurrency ببینید.

SELECT session_id, requested_memory_kb, granted_memory_kb, used_memory_kb
FROM sys.dm_exec_query_memory_grants
ORDER BY requested_memory_kb DESC;
session_idrequested_memory_kbgranted_memory_kb
57524288524288

خروجی صرفاً نمونه شکل نتیجه است؛ مقدار واقعی را از محیط خودتان با Timestamp در Baseline ثبت کنید.

مثال 6: پایش Queryهای پر CPU

تنظیم را روی Queryهای واقعاً مهم بسنجید.

SELECT TOP (10) execution_count,total_worker_time,total_elapsed_time
FROM sys.dm_exec_query_stats
ORDER BY total_worker_time DESC;
execution_counttotal_worker_timeبرداشت
1200987654321Query مهم برای Baseline

خروجی صرفاً نمونه شکل نتیجه است؛ مقدار واقعی را از محیط خودتان با Timestamp در Baseline ثبت کنید.

چرا Query Store مهم است

Query Store تاریخچه Query، Plan و Runtime را نگه می‌دارد و برای مقایسه قبل و بعد، Plan Regression و Plan Forcing ابزار کلیدی است. Memory Grant Feedback Persistence برای ماندگاری بازخورد به Query Store در حالت READ_WRITE وابسته است و Plan Feedbackهای جدید نیز از زیرساخت Query Store قابل مشاهده‌اند.

Query Store را هم نباید فقط روشن کرد و فراموش کرد. Size، Capture Policy، Read Only شدن و Retention باید مدیریت شوند. داده تاریخی ناقص، تحلیل Performance را هم ناقص می‌کند.

نسخه و Compatibility Level

Database Scoped Configuration از SQL Server 2016 وارد شد، اما همه گزینه‌های این مجموعه در همان نسخه وجود ندارند. Batch Mode on Rowstore و Scalar UDF Inlining با SQL Server 2019 و Compatibility Level 150 شناخته می‌شوند؛ Persistence و Percentile Memory Grant Feedback، DOP Feedback، CE Feedback و Optimized Plan Forcing از قابلیت‌های مهم SQL Server 2022 هستند.

نسخه Engine و Compatibility Level دو متغیر مستقل‌اند. ممکن است Engine جدید باشد ولی Database هنوز روی سطح سازگاری قدیمی اجرا شود. در مهاجرت، CU و تنظیمات Query Store را هم کنار این دو ثبت کنید.

DATABASE SCOPED PERFORMANCE - نمودار فنی 3سناریوی Baseline و Best Practice برای DATABASE SCOPED PERFORMANCEDATABASE SCOPED PERFORMANCEBaselineMAXDOPAfter ChangeUDF InliningMeasureCE/DOP FeedbackBest Practice: Query StoreMAXDOPMemory GrantAdaptive JoinUDF Inlining

Best Practice نهایی ساده است: Baseline، Change، Measure و Rollback. هیچ Feature هوشمندی جای این چرخه مهندسی را نمی‌گیرد.

سؤالات متداول

Database Scoped Configuration چیست؟

مجموعه تنظیماتی برای کنترل رفتارهای مشخص Database Engine در سطح یک پایگاه داده است تا لازم نباشد همه Workloadهای یک Instance سیاست یکسانی داشته باشند.

آیا همه گزینه‌های این مجموعه را باید ON کنیم؟

خیر. بعضی پیش‌فرض مناسب دارند، بعضی فقط در نسخه یا Compatibility مشخص معنا دارند و CLEAR PROCEDURE_CACHE اصلاً Toggle نیست.

برای شروع Performance Tuning کدام مهم‌تر است؟

اول مشکل را پیدا کنید: Query پرهزینه، Wait، Blocking، Statistics یا Index. سپس تنظیمی را بررسی کنید که مستقیم به علت مشاهده‌شده مربوط است.

آیا این Featureها جای Index Tuning را می‌گیرند؟

خیر. Query غیرSARGable، Index نامناسب و Statistics ضعیف همچنان باید ریشه‌ای اصلاح شوند.

Query Store چه نقشی دارد؟

تاریخچه Plan و Runtime، تشخیص Regression، Plan Forcing و مشاهده برخی Feedbackها را فراهم می‌کند.

برای پروژه تجاری چگونه تغییر دهیم؟

با Change Window، Baseline، تست بار، Rollback و معیار موفقیت. تغییر بدون داده قبل و بعد ریسک تشخیص را بالا می‌برد.

رایج‌ترین اشتباه چیست؟

تغییر چند Feature هم‌زمان و بعد نسبت‌دادن نتیجه به یکی از آنها بدون امکان اثبات.

چه Metricهایی مهم‌اند؟

CPU، Duration، Reads، Waits، Compile، Memory Grant، Spill، Worker و Throughput؛ Metric باید با Feature هم‌راستا باشد.

Rollback خوب چه ویژگی دارد؟

Command معکوس از قبل آماده است و بعد از اجرا مقدار تنظیم، Planها و Baseline دوباره کنترل می‌شوند.

سازگاری نسخه‌ای چگونه بررسی می‌شود؟

نسخه Engine، Compatibility Level و مستندات همان Feature را با هم ببینید؛ وجود Syntax به معنی رفتار یکسان در همه سطوح نیست.

سؤالات مصاحبه

  1. تفاوت Database Scoped و Server-level Configuration چیست؟
  2. چرا Compatibility Level در IQP مهم است؟
  3. برای Regression چه داده‌ای جمع می‌کنید؟
  4. چه زمانی Query-level Hint بهتر از تغییر Database-wide است؟
  5. چرا Clear Procedure Cache راه‌حل دائمی نیست؟
  6. Query Store چگونه به Plan Stability کمک می‌کند؟

جمع‌بندی

این ۱۷ گزینه را Toolbox ببینید، نه Checklist برای ON کردن. Parallelism، Cardinality، Memory Grant، Adaptive Execution و Plan Stability هرکدام مسئله متفاوتی دارند. تشخیص درست یعنی انتخاب ابزار متناسب با مسئله و اندازه‌گیری نتیجه.

برای مطالعه عمیق، مقاله‌های زیر هر کدام ۱۰ مثال، خروجی نمونه، FAQ، خطاهای رایج و Best Practice دارند.

خدمات برنامه‌نویسی و پایگاه داده

برنامه‌نویسی در اصفهان؛ قبول سفارش‌های برنامه‌نویسی و پایگاه داده: 09131253620. انجام پروژه، آموزش برنامه‌نویسی و آموزش پایگاه داده SQL Server برای پروژه‌های آموزشی، سازمانی و تجاری.

مجموعه‌ای معتبر با سابقه فعالیت حرفه‌ای از سال ۱۳۷۵ شمسی

از سال ۱۳۷۵ شمسی تاکنون در زمینه طراحی و اجرای پروژه‌های برنامه‌نویسی، پایگاه داده، سیستم‌های تحت وب، وب‌سایت و راهکارهای نرم‌افزاری فعالیت می‌کنیم.

برای سفارش پروژه‌های برنامه‌نویسی و پایگاه داده، سیستم‌های تحت وب، وب‌سایت و راهکارهای نرم‌افزاری جدید با شماره 09131253620 تماس حاصل فرمایید.

ایتا، واتساپ و تماس مستقیم: +989131253620

تماس با ما

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

حرف 500 حداکثر