Execution Plan কী?

Execution Plan হলো ডেটাবেজ Query Optimizer-এর তৈরি করা একটি Blueprint বা পরিকল্পনা যে কীভাবে একটি SQL Query কার্যকর করা হবে। কোন Index ব্যবহার হবে, কীভাবে টেবিল Join হবে, কতটি Row স্ক্যান হবে — এসব তথ্য Execution Plan-এ থাকে।


কেন Execution Plan গুরুত্বপূর্ণ?

  • Slow Query খুঁজে বের করা: কেন Query ধীর তা বুঝতে সাহায্য করে
  • Index কার্যকর কিনা যাচাই: Index ব্যবহার হচ্ছে কিনা দেখা যায়
  • Query Optimization: কোথায় উন্নতি করা যাবে বোঝা যায়
  • Full Table Scan শনাক্ত: অপ্রয়োজনীয় Full Scan ধরা যায়

EXPLAIN কমান্ড

MySQL-এ EXPLAIN

-- Basic EXPLAIN
EXPLAIN SELECT * FROM employees WHERE email = 'test@test.com';

-- Output:
-- +----+-------------+-----------+------+----------------+----------------+---------+-------+------+---------+
-- | id | select_type | table     | type | possible_keys  | key            | key_len | ref   | rows | Extra   |
-- +----+-------------+-----------+------+----------------+----------------+---------+-------+------+---------+
-- |  1 | SIMPLE      | employees | ref  | idx_emp_email  | idx_emp_email  | 768     | const |    1 | ...     |
-- +----+-------------+-----------+------+----------------+----------------+---------+-------+------+---------+

মূল কলামের অর্থ:

কলাম অর্থ
type কিভাবে টেবিল এক্সেস করা হচ্ছে (const, ref, range, ALL)
possible_keys কোন Index ব্যবহার হতে পারে
key কোন Index আসলে ব্যবহার হচ্ছে
rows কতটি Row স্ক্যান হবে (আনুমানিক)
Extra অতিরিক্ত তথ্য (Using index, Using filesort)

type কলামের মান (সেরা থেকে সবচেয়ে খারাপ):

const   → Primary Key বা Unique Key দিয়ে একটি Row (সবচেয়ে দ্রুত)
eq_ref  → JOIN-এ Primary Key ব্যবহার
ref     → Non-unique Index ব্যবহার
range   → Index-এ Range scan
index   → Full Index scan
ALL     → Full Table scan (সবচেয়ে ধীর — এড়িয়ে চলুন!)

PostgreSQL-এ EXPLAIN

-- Basic EXPLAIN
EXPLAIN SELECT * FROM employees WHERE salary > 50000;

-- EXPLAIN ANALYZE: আনুমানিক নয়, আসল সময় দেখায়
EXPLAIN ANALYZE SELECT * FROM employees WHERE salary > 50000;

-- Output:
-- Seq Scan on employees  (cost=0.00..2847.00 rows=9745 width=65) (actual time=0.012..15.234 rows=9741 loops=1)
--   Filter: (salary > 50000)
--   Rows Removed by Filter: 255
-- Planning Time: 0.134 ms
-- Execution Time: 15.891 ms

PostgreSQL Output বোঝার গাইড:

Seq Scan → Sequential (Full) Table Scan (ধীর)
Index Scan → Index ব্যবহার করছে (দ্রুত)
Index Only Scan → Covering Index (সবচেয়ে দ্রুত)
Bitmap Heap Scan → Bitmap Index Scan (মাঝারি)

cost=0.00..2847.00 → (startup cost)..(total cost)
rows=9745 → আনুমানিক Row সংখ্যা
actual time=0.012..15.234 → আসল সময় (ANALYZE দিলে)

সাধারণ সমস্যা ও সমাধান

১. Full Table Scan (ALL)

-- সমস্যা: Index নেই
EXPLAIN SELECT * FROM orders WHERE status = 'PENDING';
-- type: ALL, rows: 1000000 (ধীর!)

-- সমাধান: Index যোগ করুন
CREATE INDEX idx_orders_status ON orders(status);

-- এখন:
-- type: ref, rows: 150 (দ্রুত!)

২. Index ব্যবহার না হওয়া

-- সমস্যা: Function ব্যবহার Index নষ্ট করে
EXPLAIN SELECT * FROM employees WHERE YEAR(hire_date) = 2023;
-- type: ALL (Index নেই!)

-- সমাধান: Range Query ব্যবহার
SELECT * FROM employees
WHERE hire_date BETWEEN '2023-01-01' AND '2023-12-31';
-- type: range (Index ব্যবহার হচ্ছে!)

৩. Filesort সমস্যা

-- সমস্যা: ORDER BY-তে Index নেই
EXPLAIN SELECT * FROM products ORDER BY price DESC LIMIT 20;
-- Extra: Using filesort (ধীর!)

-- সমাধান: price-এ Index যোগ করুন
CREATE INDEX idx_products_price ON products(price DESC);
-- Extra: Using index (দ্রুত!)

Spring Boot-এ Slow Query Log

# application.properties-এ Slow Query লগ করুন
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

# Slow Query threshold: 100ms এর বেশি লাগলে log করো
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql=TRACE
// Hibernate Statistics দিয়ে Query Performance দেখুন
@Configuration
public class HibernateConfig {

    @Bean
    public HibernatePropertiesCustomizer hibernateStatistics() {
        return properties -> {
            properties.put(AvailableSettings.GENERATE_STATISTICS, true);
            properties.put(AvailableSettings.LOG_SLOW_QUERIES, 100); // 100ms
        };
    }
}

EXPLAIN ANALYZE বাস্তব উদাহরণ

-- জটিল JOIN Query-র Execution Plan
EXPLAIN ANALYZE
SELECT c.name, COUNT(o.id) as order_count, SUM(o.total) as total_spent
FROM customers c
JOIN orders o ON c.id = o.customer_id
WHERE o.created_at > '2024-01-01'
GROUP BY c.id, c.name
ORDER BY total_spent DESC
LIMIT 10;

-- Output বিশ্লেষণ:
-- Limit  (cost=... rows=10) (actual time=234.5..234.6 rows=10)
--   Sort  (cost=... rows=...) (actual time=234.5..234.5 rows=10)
--     HashAggregate  (cost=...) (actual time=230.1..231.2 rows=1523)
--       Hash Join  (cost=...) (actual time=12.3..225.6 rows=45231)
--         Seq Scan on customers  ← Index নেই!
--         Index Scan on orders   ← Index আছে (created_at index)

-- সমাধান: customers-এ Index যোগ করুন
-- CREATE INDEX idx_customers_id ON customers(id);

সংক্ষেপে

বিষয় বিবরণ
Execution Plan Query কিভাবে চলবে তার পরিকল্পনা
EXPLAIN MySQL/PostgreSQL-এ Plan দেখানোর কমান্ড
EXPLAIN ANALYZE আসল সময় সহ Plan (PostgreSQL)
type: ALL Full Table Scan — সবচেয়ে ধীর
type: const Exact match — সবচেয়ে দ্রুত
Using filesort ORDER BY-তে Index নেই
Using index Covering Index ব্যবহার হচ্ছে

উপসংহার

Execution Plan ডেটাবেজ Performance Tuning-এর সবচেয়ে গুরুত্বপূর্ণ টুল। EXPLAIN কমান্ড ব্যবহার করে Full Table Scan শনাক্ত করুন, Index কার্যকরতা যাচাই করুন এবং Slow Query Optimize করুন। Spring Boot-এ Hibernate Statistics এবং Slow Query Log সক্রিয় রাখলে Performance সমস্যা দ্রুত ধরা যায়।

Share