Oracle ডেটাবেজ পারফরম্যান্স টিউনিং: AWR, ADDM, Wait Events ও SQL অপটিমাইজেশন গাইড
গত কোয়ার্টারে যে কোয়েরি ৩ সেকেন্ডে চলত, সেটি এখন ৪৫ সেকেন্ড নিচ্ছে। ERP অ্যাপ্লিকেশনটি প্রতিদিন সকাল ৯টা থেকে ১১টার মধ্যে ধীর হয়ে যায়। দিন শেষের ব্যাচ তার নির্ধারিত সময়সীমা ছাড়িয়ে যাচ্ছে। ব্যবহারকারীরা অভিযোগ করছেন কিন্তু কেন হচ্ছে কেউ জানে না। এগুলোই সেই পারফরম্যান্স সমস্যা যেগুলোর মুখোমুখি Oracle DBA-রা প্রোডাকশনে হন — আর এগুলো সমাধানের জন্য Oracle আপনাকে ডেটাবেজ ইন্ডাস্ট্রির অন্যতম পূর্ণাঙ্গ ডায়াগনস্টিক টুলকিট দেয়। এই গাইডে সম্পূর্ণ পারফরম্যান্স টিউনিং মেথডোলজি তুলে ধরা হয়েছে: AWR রিপোর্ট পড়া ও ADDM সুপারিশ অনুযায়ী কাজ করা থেকে শুরু করে wait events নির্ণয়, SQL execution plan অপটিমাইজ করা এবং মেমরি টিউনিং পর্যন্ত। এই মেথডোলজিই ম্যানুফ্যাকচারিং ERP, ব্যাংক কোর সিস্টেম এবং ফার্মা প্রোডাকশন ডেটাবেজের পারফরম্যান্স সমস্যা সমাধান করেছে।
১. সঠিক পন্থা: Top-Down টিউনিং
Oracle পারফরম্যান্স টিউনিংয়ে সবচেয়ে বড় ভুল হলো ভুল স্তর থেকে শুরু করা। অনেক DBA প্রথমে ডেটাবেজ আসলে কীসের জন্য অপেক্ষা করছে তা না বুঝেই সরাসরি SQL অপটিমাইজেশনে ঝাঁপিয়ে পড়েন — কোয়েরি নতুন করে লেখা, index যোগ করা। যে কোয়েরি disk I/O-এর জন্য অপেক্ষা করার কারণে ৩০ সেকেন্ড নিচ্ছে, তার সমাধান lock contention বা missing index-এর কারণে ৩০ সেকেন্ড নেওয়া কোয়েরির থেকে আলাদা।
সঠিক top-down মেথডোলজি:
- সিস্টেম স্তর: ডেটাবেজ তার সময় কীসের পেছনে ব্যয় করছে? (AWR, ADDM, wait events)
- সেশন স্তর: কোন সেশনগুলো সবচেয়ে বেশি রিসোর্স ব্যবহার করছে?
- SQL স্তর: কোন SQL স্টেটমেন্টগুলো সবচেয়ে বড় ভোক্তা?
- Execution plan স্তর: ওই SQL স্টেটমেন্টগুলো কি দক্ষ plan ব্যবহার করছে?
- স্কিমা স্তর: index, statistics এবং ডেটা স্ট্রাকচার কি সর্বোত্তম?
- মেমরি স্তর: SGA এবং PGA কি ওয়ার্কলোড অনুযায়ী সঠিক আকারে আছে?
২. AWR — Automatic Workload Repository
AWR হলো Oracle-এর বিল্ট-ইন পারফরম্যান্স স্ন্যাপশট রিপোজিটরি। প্রতি ঘণ্টায় (কনফিগারযোগ্য) Oracle শত শত সিস্টেম statistics-এর একটি স্ন্যাপশট ধারণ করে — wait events, SQL execution statistics, মেমরি ব্যবহার, I/O রেট। দুটি স্ন্যাপশট তুলনা করলে আপনি ওই সময়কালের একটি পারফরম্যান্স রিপোর্ট পান।
২.১ AWR রিপোর্ট তৈরি করা
-- Generate AWR HTML report (most useful format — readable in browser)
-- First, find the snapshot IDs for the period of interest
SELECT snap_id,
TO_CHAR(begin_interval_time,'DD-MON-YYYY HH24:MI') AS snap_time,
ROUND(snap_interval) AS interval_min
FROM DBA_HIST_SNAPSHOT
WHERE begin_interval_time BETWEEN
TO_TIMESTAMP('2026-06-04 09:00','YYYY-MM-DD HH24:MI') AND
TO_TIMESTAMP('2026-06-04 11:00','YYYY-MM-DD HH24:MI')
ORDER BY snap_id;
-- Generate report: replace begin_snap and end_snap with actual IDs
SELECT OUTPUT FROM TABLE(
DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML(
l_dbid => (SELECT dbid FROM V$DATABASE),
l_inst_num => 1,
l_bid => 1234, -- begin snapshot ID
l_eid => 1236 -- end snapshot ID
)
);
-- Or use the script (easier)
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
২.২ AWR রিপোর্টে সবচেয়ে গুরুত্বপূর্ণ পাঁচটি সেকশন
সেকশন ১: DB Time এবং Load Profile
DB Time হলো সমস্ত সেশন মিলে ডেটাবেজের কাজে ব্যয় করা মোট সময়। প্রতি সেকেন্ডে DB Time যদি elapsed time-এর চেয়ে উল্লেখযোগ্যভাবে বেশি হয়, তাহলে ডেটাবেজটি ভারী লোডের মধ্যে আছে। Load Profile প্রতি সেকেন্ডে ট্রানজেকশন, logical reads এবং physical reads দেখায় — আপনার বেসলাইন মেট্রিক।
সেকশন ২: Top 10 Foreground Events
এটিই সবচেয়ে গুরুত্বপূর্ণ সেকশন। এটি আপনাকে বলে দেয় স্ন্যাপশট সময়কালে Oracle কীসের জন্য সবচেয়ে বেশি অপেক্ষা করছিল। শীর্ষ wait event ৭০–৮০% পারফরম্যান্স সমস্যার ব্যাখ্যা দেয়।
- db file sequential read: Single-block reads — সাধারণত index lookup। বেশি মান মানে প্রচুর physical I/O সহ index scan — SQL টিউন করুন বা স্টোরেজ গতি বাড়ান
- db file scattered read: Multi-block reads — full table scan। missing index বা যেসব full scan-এ index থাকা উচিত ছিল তা নির্দেশ করে
- log file sync: COMMIT-এর সময় LGWR যেন redo disk-এ লেখে তার জন্য অপেক্ষা। বেশি মান মানে অনেক ছোট ছোট commit, ধীর redo log স্টোরেজ, অথবা redo log খুব ছোট আকারের
- enq: TX - row lock contention: Row-level locking — একটি সেশন আরেকটিকে ব্লক করছে। অ্যাপ্লিকেশন lock খুব বেশিক্ষণ ধরে রাখছে
- CPU time: ডেটাবেজটি CPU-bound — অপেক্ষা করছে না, শুধু গণনা করছে। সাধারণত sorting, hashing বা উচ্চ-ভলিউম কোয়েরি প্রসেসিং বোঝায়
- buffer busy waits: একই buffer block-এর জন্য একাধিক সেশনের প্রতিযোগিতা — hot block contention, প্রায়ই sequence generator বা ঘন ঘন আপডেট হওয়া index block-এ
সেকশন ৩: SQL Statistics
Elapsed time, CPU, logical reads, physical reads এবং executions অনুযায়ী শীর্ষ SQL। সবচেয়ে খারাপ পারফর্ম করা স্টেটমেন্টগুলোর SQL ID-ই আপনার পরবর্তী ডায়াগনস্টিক লক্ষ্য।
সেকশন ৪: Instance Activity Statistics
Physical reads, logical reads, redo size, user commits, user rollbacks, parse counts। অস্বাভাবিকতা শনাক্ত করতে এগুলো আপনার বেসলাইনের সাথে তুলনা করুন।
সেকশন ৫: Segment Statistics
Logical reads, physical reads, buffer busy waits অনুযায়ী শীর্ষ segment। hot table এবং index শনাক্ত করে — partitioning, caching বা I/O অপটিমাইজেশনের প্রার্থী।
৩. ADDM — Automatic Database Diagnostic Monitor
ADDM স্বয়ংক্রিয়ভাবে AWR ডেটা বিশ্লেষণ করে অগ্রাধিকার-ক্রমে সাজানো সুপারিশ তৈরি করে। এটি Oracle-এর সবচেয়ে কম ব্যবহৃত টুলগুলোর একটি — অনেক DBA AWR ডেটা সংগ্রহ করেন কিন্তু তা থেকে Oracle-এর তৈরি ADDM findings পড়েন না।
-- View the latest ADDM report
SELECT task_name, description, status,
TO_CHAR(created,'DD-MON-YYYY HH24:MI') AS created
FROM DBA_ADVISOR_TASKS
WHERE advisor_name = 'ADDM'
ORDER BY created DESC
FETCH FIRST 5 ROWS ONLY;
-- Read ADDM findings with recommendations
SELECT f.impact_type, f.impact,
f.message AS finding,
r.message AS recommendation
FROM DBA_ADVISOR_FINDINGS f
JOIN DBA_ADVISOR_RECOMMENDATIONS r
ON f.task_name = r.task_name
AND f.finding_id = r.finding_id
WHERE f.task_name = (
SELECT task_name FROM DBA_ADVISOR_TASKS
WHERE advisor_name = 'ADDM'
ORDER BY created DESC
FETCH FIRST 1 ROW ONLY
)
ORDER BY f.impact DESC;
ADDM findings impact অনুযায়ী ক্রমবিন্যস্ত হয় — অর্থাৎ সমস্যাটির জন্য দায়ী DB Time-এর শতকরা হার। প্রথমে ১০%-এর বেশি impact-এর findings-এ মনোযোগ দিন।
৩.১ সাধারণ ADDM সুপারিশ এবং পদক্ষেপ
| ADDM Finding | সাধারণ মূল কারণ | পদক্ষেপ |
|---|---|---|
| উল্লেখযোগ্য DB Time গ্রাসকারী SQL স্টেটমেন্ট | Untuned SQL, missing index | ওই SQL ID-তে SQL Tuning Advisor চালান |
| Hard parsing CPU গ্রাস করছে | SQL-এ literal (bind variable নয়) | CURSOR_SHARING=FORCE সেট করুন বা অ্যাপ্লিকেশন ঠিক করুন |
| datafile সম্পর্কিত I/O | ধীর স্টোরেজ, hot datafile | hot datafile দ্রুততর স্টোরেজ টিয়ারে সরান |
| Undersized SGA components | Buffer cache বা shared pool খুব ছোট | SGA_TARGET বাড়ান |
| অতিরিক্ত log file sync waits | ধীর redo log বা অনেক বেশি commit | redo log দ্রুততর disk-এ সরান; batch commit ব্যবহার করুন |
৪. Wait Event নির্ণয়
Wait events হলো Oracle-এর ডায়াগনস্টিক ভাষা। যখন একটি সেশন এগোতে পারে না — একটি lock, একটি disk read, একটি network response-এর জন্য অপেক্ষা করছে — Oracle wait event এবং তার সময়কাল রেকর্ড করে। wait events সঠিকভাবে পড়া সরাসরি মূল কারণের দিকে নিয়ে যায়।
৪.১ রিয়েল-টাইম Wait Event মনিটরিং
-- Current wait events across all active sessions
SELECT s.sid, s.username, s.status,
s.event AS wait_event,
s.wait_time,
s.seconds_in_wait,
s.sql_id,
SUBSTR(q.sql_text,1,60) AS sql_preview
FROM V$SESSION s
LEFT JOIN V$SQL q ON s.sql_id = q.sql_id
WHERE s.status = 'ACTIVE'
AND s.username IS NOT NULL
AND s.event NOT LIKE '%idle%'
ORDER BY s.seconds_in_wait DESC;
৪.২ সবচেয়ে সাধারণ Wait Events নির্ণয়
db file sequential read (উচ্চ Physical I/O)
-- Find SQL causing the most physical reads
SELECT sql_id, plan_hash_value,
disk_reads, executions,
ROUND(disk_reads/NULLIF(executions,0)) AS reads_per_exec,
SUBSTR(sql_text,1,80) AS sql_preview
FROM V$SQL
WHERE disk_reads > 10000
ORDER BY disk_reads DESC
FETCH FIRST 20 ROWS ONLY;
log file sync (ধীর Commit)
-- Check redo log write performance
SELECT l.group#, l.members, l.bytes/1024/1024 AS size_mb,
l.status, lf.member AS log_file
FROM V$LOG l
JOIN V$LOGFILE lf ON l.group# = lf.group#
ORDER BY l.group#;
-- Check if redo logs need to be moved to faster storage
-- Average log file sync wait > 5ms = storage issue for redo logs
SELECT event, total_waits,
ROUND(time_waited/total_waits,2) AS avg_wait_ms
FROM V$SYSTEM_EVENT
WHERE event = 'log file sync';
enq: TX - row lock contention
-- Find who is blocking whom RIGHT NOW
SELECT
DECODE(request,0,'Blocker','Waiter') AS lock_type,
sid, type, id1, id2, lmode, request,
ctime AS seconds_held_or_waited,
block
FROM V$LOCK
WHERE (id1,id2,type) IN (
SELECT id1,id2,type FROM V$LOCK WHERE block=1
)
ORDER BY id1, id2, request;
৫. SQL টিউনিং — খারাপ Execution Plan খুঁজে বের করা ও ঠিক করা
AWR থেকে সবচেয়ে খারাপ পারফর্ম করা SQL শনাক্ত করার পর, পরবর্তী ধাপ হলো এটি কেন ধীর তা নির্ণয় করা এবং ঠিক করা।
৫.১ একটি Execution Plan পড়া
-- Get the current execution plan for a SQL statement
SELECT * FROM TABLE(
DBMS_XPLAN.DISPLAY_CURSOR(
sql_id => '&sql_id',
cursor_child_no => 0,
format => 'ALLSTATS LAST +PEEKED_BINDS'
)
);
-- Or explain a query directly
EXPLAIN PLAN FOR
SELECT c.customer_name, SUM(o.order_value)
FROM customers c JOIN orders o ON c.customer_id = o.customer_id
WHERE o.order_date > SYSDATE - 30
GROUP BY c.customer_name;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
৫.২ একটি Execution Plan-এ কী দেখতে হবে
- বড় টেবিলে FULL TABLE SCAN: সাধারণত missing index বোঝায় — WHERE clause-এর কলামগুলো পরীক্ষা করুন
- Estimated rows বনাম Actual rows-এ বড় পার্থক্য: Stale statistics — DBMS_STATS.GATHER_TABLE_STATS চালান
- বড় result set-এ Nested Loop join: বড় টেবিলের জন্য Hash Join হওয়া উচিত — optimizer-এর cardinality estimate ভুল হতে পারে
- উচ্চ A-Rows (actual) কিন্তু নিম্ন E-Rows (estimated): Statistics পুরনো — optimizer ভুল plan বেছেছে
- index সমর্থন ছাড়া SORT অপারেশন: ORDER BY বা GROUP BY কলামগুলো index দ্বারা সমর্থিত নয় — index যোগ করুন বা PGA বাড়ান
৫.৩ SQL Tuning Advisor
-- Run SQL Tuning Advisor on a specific SQL ID
DECLARE
l_task_name VARCHAR2(30);
BEGIN
l_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_id => '&bad_sql_id',
scope => DBMS_SQLTUNE.SCOPE_COMPREHENSIVE,
time_limit => 60,
task_name => 'TUNE_BAD_SQL',
description => 'Tuning slow query from AWR'
);
DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => 'TUNE_BAD_SQL');
END;
/
-- Read the recommendations
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('TUNE_BAD_SQL')
FROM DUAL;
৫.৪ SQL Plan Management (SPM) — Plan Regression প্রতিরোধ
Oracle-এর সবচেয়ে ক্ষতিকর পারফরম্যান্স সমস্যাগুলোর একটি হলো এমন একটি কোয়েরি যা বছরের পর বছর দ্রুত ছিল কিন্তু statistics রিফ্রেশ বা একটি আপগ্রেডের পর optimizer ভিন্ন plan বেছে নেওয়ায় হঠাৎ ধীর হয়ে গেল। SQL Plan Management ভালো plan-টি লক করে এই সমস্যা প্রতিরোধ করে।
-- Capture a good plan into SQL Plan Baseline
VAR ret NUMBER
BEGIN
:ret := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
sql_id => '&good_sql_id',
plan_hash_value => &good_plan_hash
);
END;
/
-- Verify the baseline was created
SELECT sql_handle, plan_name, enabled, accepted, fixed
FROM DBA_SQL_PLAN_BASELINES
WHERE sql_text LIKE '%your_query_fragment%';
৬. Index অপটিমাইজেশন
Index হলো সবচেয়ে শক্তিশালী SQL টিউনিং টুল — এবং সবচেয়ে বেশি ভুলভাবে ব্যবহৃত। খুব কম index full table scan-এর কারণ হয়। খুব বেশি index DML ধীর করে এবং কোনো সুবিধা ছাড়াই স্টোরেজ গ্রাস করে।
৬.১ Missing Index খুঁজে বের করা
-- Tables with high full scan counts — candidates for index review
SELECT o.object_name AS table_name,
s.value AS full_scans
FROM V$SEGMENT_STATISTICS s
JOIN DBA_OBJECTS o ON s.obj# = o.object_id
WHERE s.statistic_name = 'table scans (long tables)'
AND s.value > 500
AND o.object_type = 'TABLE'
ORDER BY s.value DESC
FETCH FIRST 20 ROWS ONLY;
৬.২ অব্যবহৃত Index খুঁজে বের করা
-- Monitor index usage for 2-4 weeks then check
ALTER INDEX erp.idx_orders_customer MONITORING USAGE;
-- After monitoring period, check which indexes were NOT used
SELECT index_name, table_name, used, monitoring
FROM V$OBJECT_USAGE
WHERE used = 'NO' AND monitoring = 'YES'
ORDER BY table_name, index_name;
৬.৩ Index Rebuild করা
-- Check index fragmentation (rebuild if PCT_USED < 50%)
ANALYZE INDEX erp.idx_transactions_date VALIDATE STRUCTURE;
SELECT name, del_lf_rows, lf_rows,
ROUND(del_lf_rows/NULLIF(lf_rows,0)*100,1) AS pct_deleted,
btree_space, used_space,
ROUND(used_space/btree_space*100,1) AS pct_used
FROM INDEX_STATS;
-- Rebuild fragmented index online (no downtime)
ALTER INDEX erp.idx_transactions_date REBUILD ONLINE;
৭. মেমরি টিউনিং — SGA এবং PGA
৭.১ SGA কম্পোনেন্ট সাইজিং
-- Check buffer cache hit ratio (should be > 95% for OLTP)
SELECT
ROUND((1-(pr.value/(dbg.value+cg.value)))*100,2) AS buffer_hit_pct
FROM V$SYSSTAT pr, V$SYSSTAT dbg, V$SYSSTAT cg
WHERE pr.name='physical reads'
AND dbg.name='db block gets'
AND cg.name='consistent gets';
-- Buffer Cache Advisor: recommended size for 95% hit ratio
SELECT size_for_estimate AS cache_mb,
ROUND(physical_reads_factor,3) AS io_factor,
ROUND(estd_physical_read_time,0) AS estd_io_time
FROM V$DB_CACHE_ADVICE
WHERE block_size = (SELECT value FROM V$PARAMETER WHERE name='db_block_size')
AND advice_status = 'ON'
ORDER BY size_for_estimate;
-- Shared Pool sizing
SELECT component, current_size/1024/1024 AS current_mb,
min_size/1024/1024 AS min_mb,
last_oper_type AS last_resize
FROM V$SGA_DYNAMIC_COMPONENTS
WHERE component IN ('shared pool','buffer cache','large pool','java pool');
৭.২ PGA টিউনিং
-- Check PGA usage and optimal/one-pass/multi-pass workarea stats
SELECT name, value
FROM V$PGASTAT
WHERE name IN (
'aggregate PGA target parameter',
'aggregate PGA auto target',
'global memory bound',
'total PGA inuse',
'total PGA allocated',
'maximum PGA allocated',
'cache hit percentage'
);
-- If cache_hit_percentage < 90%, increase PGA_AGGREGATE_TARGET
-- Workarea execution modes (optimal = no disk spill)
SELECT ROUND(optimal_executions/(optimal_executions +
onepass_executions + multipass_executions)*100,1) AS pct_optimal
FROM (
SELECT SUM(DECODE(operation_type,'SORT',optimal_executions,0)) AS optimal_executions,
SUM(DECODE(operation_type,'SORT',onepass_executions,0)) AS onepass_executions,
SUM(DECODE(operation_type,'SORT',multipasses_executions,0)) AS multipass_executions
FROM V$SQL_WORKAREA_HISTOGRAM
);
৮. Statistics সংগ্রহ ও ব্যবস্থাপনা
Stale বা missing optimizer statistics execution plan regression-এর একটি বড় অংশের জন্য দায়ী। একটি সঠিক statistics কৌশল পারফরম্যান্স ব্যবস্থাপনার অংশ।
-- Check tables with stale statistics
SELECT owner, table_name, last_analyzed,
num_rows, stale_stats
FROM DBA_TAB_STATISTICS
WHERE stale_stats = 'YES'
AND owner = 'ERP'
ORDER BY last_analyzed NULLS FIRST;
-- Gather statistics with auto-sampling (recommended for most tables)
EXEC DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'ERP',
tabname => 'TRANSACTIONS',
cascade => TRUE,
degree => 8,
method_opt => 'FOR ALL COLUMNS SIZE AUTO'
);
-- For large tables: gather with incremental statistics (partitioned)
EXEC DBMS_STATS.SET_TABLE_PREFS(
ownname => 'ERP',
tabname => 'TRANSACTIONS',
pname => 'INCREMENTAL',
pvalue => 'TRUE'
);
৯. বাস্তব পারফরম্যান্স টিউনিং কেস
আমার প্রোডাকশন অভিজ্ঞতা থেকে তিনটি বাস্তব কেস:
কেস ১ — ম্যানুফ্যাকচারিং ERP সকাল ৯–১১টায় ধীর
উপসর্গ: ERP অ্যাপ্লিকেশন প্রতিদিন সকালে সাধারণ inventory কোয়েরিতে ২০–৪০ সেকেন্ড নিত। বিকেল নাগাদ স্বাভাবিক গতি।
নির্ণয়: AWR দেখাল শীর্ষ wait event ছিল inventory sequence generator-এর একটি নির্দিষ্ট block-এ buffer busy waits। একই সময়ে একাধিক ব্যবহারকারী sequence number চাওয়ায় তারা সবাই একই cached block-এ আঘাত করছিল।
সমাধান: sequence CACHE প্যারামিটার ২০ থেকে ৫০০-তে পরিবর্তন করলাম। hot block contention দূর হলো। কোয়েরি সময় ১ সেকেন্ডের নিচে ফিরে এল।
কেস ২ — ব্যাংক EOD ব্যাচ সময়সীমা ছাড়িয়ে যাচ্ছে
উপসর্গ: দিন শেষের অ্যাকাউন্ট পোস্টিং ব্যাচ ৩ ঘণ্টার বদলে ৬ ঘণ্টা নিত, ব্যবসায়িক দিনের শুরু ছাড়িয়ে যাচ্ছিল।
নির্ণয়: ADDM একটি একক SQL স্টেটমেন্ট শনাক্ত করল যা DB Time-এর ৪৫%-এর জন্য দায়ী — একটি balance summary কোয়েরি ২০ কোটি row-এ full table scan করছিল, কারণ partitioned টেবিলে statistics partition স্তরে হিসাব করা ছিল কিন্তু কোয়েরিটি global টেবিল অ্যাক্সেস করছিল।
সমাধান: GRANULARITY=>'ALL' দিয়ে global statistics সংগ্রহ করলাম। optimizer full table scan-এর বদলে partition pruning বেছে নিল। ব্যাচ ৬ ঘণ্টা থেকে ২.৫ ঘণ্টায় নেমে এল।
কেস ৩ — Patch-এর পর ফার্মা প্রোডাকশন ডেটাবেজ ধীর
উপসর্গ: একটি CPU patch প্রয়োগের পর ৩টি গুরুত্বপূর্ণ প্রোডাকশন কোয়েরি ২ সেকেন্ড থেকে এক মিনিটেরও বেশিতে regress করল।
নির্ণয়: patch-টি কিছু optimizer প্যারামিটার নতুন default-এ রিসেট করেছিল, যার ফলে plan regression হয়। এই কোয়েরিগুলোর জন্য SQL Plan Baselines ছিল না।
সমাধান: SQL Plan Management ব্যবহার করে patch-পূর্ববর্তী ভালো plan-গুলো SQL Plan Baselines-এ লোড করলাম। কোয়েরিগুলো সাথে সাথে দ্রুত plan-এ ফিরে এল। Baseline ভবিষ্যতের plan regression প্রতিরোধ করে।
⚡ আপনার Oracle ডেটাবেজ কি পূর্ণ গতিতে চলছে?
আমি Oracle পারফরম্যান্স সমস্যা নির্ণয় ও সমাধান করি — ধীর কোয়েরি, উচ্চ wait events, মেমরি সাইজিং, index অপটিমাইজেশন এবং execution plan regression। বাংলাদেশ ও বিশ্বজুড়ে ক্লায়েন্ট।
শেষ কথা
Oracle পারফরম্যান্স টিউনিং একটি শৃঙ্খলা, কোনো কৌশলের ঝুলি নয়। যে DBA AWR দিয়ে শুরু করেন, শীর্ষ wait events পড়েন, সর্বোচ্চ-impact ADDM findings শনাক্ত করেন এবং তারপর ধারাবাহিকভাবে SQL-স্তরের অপটিমাইজেশন পর্যন্ত নেমে আসেন, তিনি ধারাবাহিকভাবে পারফরম্যান্স সমস্যা সমাধান করবেন। যে DBA এলোমেলোভাবে index যোগ করেন, পরিমাপ ছাড়াই প্যারামিটার পরিবর্তন করেন এবং ডেটা না দেখে অ্যাপ্লিকেশনকে দোষ দেন, তিনি বারবার একই সমস্যার আগুন নেভাতে সময় ব্যয় করবেন।
Oracle যে টুলগুলো দেয় — AWR, ADDM, SQL Tuning Advisor, SQL Plan Management — সেগুলো সত্যিই চমৎকার। এগুলো ক্রম অনুযায়ী ব্যবহার করুন, প্রতিটি পরিবর্তনের আগে ও পরে পরিমাপ করুন, এবং কী কাজ করল তা নথিভুক্ত করুন। পরিমাপ ছাড়া পারফরম্যান্স টিউনিং মানে অনুমান করা।
তথ্যসূত্র ও আরও পড়ুন
- 📄 Oracle Database Performance Tuning Guide (19c) — AWR, ADDM, and Wait Events
- 📄 Oracle SQL Tuning Guide — Execution Plans and SQL Tuning Advisor
- 📄 Oracle SQL Plan Management (SPM) — Controlling Execution Plans
- 📄 Oracle Optimizer Statistics — Gathering and Managing Statistics
- 📄 Oracle Memory Configuration — SGA and PGA Tuning
এই লেখার টিউনিং মেথডোলজি ও কেস স্টাডিগুলো ম্যানুফ্যাকচারিং, ব্যাংকিং ও ফার্মাসিউটিক্যাল প্রোডাকশন পরিবেশে ১৮+ বছরের Oracle পারফরম্যান্স নির্ণয়ের অভিজ্ঞতার উপর ভিত্তি করে তৈরি।
