Tối ưu hoá Query Performance trong MySQL / PostgreSQL: Phân tích Explain Plan và tối ưu Index cho các query phức tạp
⚡ Mục tiêu – Giảm thời gian thực thi trung bình của các query “đèn đỏ” xuống < 200 ms, đồng thời duy trì khả năng mở rộng khi lưu lượng tăng ≥ 30 %/tháng.
1. Tổng quan quy trình (Workflow)
┌─────────────────────┐ 1️⃣ Thu thập log query
│ Log Collector │ ─────────────────────►
└─────────┬───────────┘
│
▼
┌─────────────────────┐ 2️⃣ Phân tích Explain Plan
│ Explain Analyzer │ ─────────────────────►
└───────┬──────────────┘
│
▼
┌─────────────────────┐ 3️⃣ Đề xuất Index
│ Index Planner │ ─────────────────────►
└───────┬──────────────┘
│
▼
┌─────────────────────┐ 4️⃣ Kiểm thử (Staging)
│ Test Runner │ ─────────────────────►
└───────┬──────────────┘
│
▼
┌─────────────────────┐ 5️⃣ Deploy & Monitor
│ CI/CD Pipeline │ ─────────────────────►
└─────────────────────┘
import json, re, subprocess
def run_explain(query):
cmd = f"mysql -u app_user -psecret -e 'EXPLAIN FORMAT=JSON {query}'"
out = subprocess.check_output(cmd, shell=True)
return json.loads(out.decode())
def parse_cost(plan):
return plan['query_block']['cost_info']['total_cost']
# Example
q = "SELECT * FROM orders WHERE customer_id = 12345"
plan = run_explain(q)
print("Cost:", parse_cost(plan))
6.4 PostgreSQL index suggestion (SQL)
-- Extension for index usage statistics
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- View candidate columns
SELECT
relname,
pg_size_pretty(pg_relation_size(relid)) AS table_size,
pg_get_indexdef(indexrelid) AS index_def
FROM pg_stat_user_indexes
WHERE idx_scan = 0;
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
if (url.pathname.startsWith('/explain/')) {
const cacheKey = new Request(url.toString(), request)
const cache = caches.default
let response = await cache.match(cacheKey)
if (!response) {
response = await fetch(request) // forward to backend
response = new Response(response.body, response)
response.headers.append('Cache-Control', 'public, max-age=300')
await cache.put(cacheKey, response.clone())
}
return response
}
return fetch(request)
}
6.9 Script đối soát payment (Node.js)
const pg = require('pg')
const client = new pg.Client({ connectionString: process.env.PG_URI })
async function reconcile() {
await client.connect()
const res = await client.query(`
SELECT order_id, SUM(amount) AS total_paid
FROM payments
GROUP BY order_id
HAVING SUM(amount) <> (SELECT total FROM orders WHERE id = order_id)
`)
console.log('Mismatched orders:', res.rowCount)
await client.end()
}
reconcile()
🛡️ Lưu ý: Các phase có hard dependency (đánh dấu “→”) và soft dependency (có thể chạy song song nếu tài nguyên đủ).
12. Các công thức tính toán (LaTeX)
Chi phí dự kiến 30 tháng
Trong đó:
Price_i = giá mỗi GB (USD) của công nghệ i
Storage_i = dung lượng dự kiến (GB)
Tỷ lệ cải thiện latency
13. Key Takeaways
✅
Nội dung
Explain Plan là nguồn dữ liệu duy nhất để xác định “đèn đỏ” trong query.
Index coverage ≥ 90 % thường giảm latency 60‑80 % và giảm I/O.
Online DDL giúp tạo index mà không gây downtime đáng kể.
CI/CD + Liquibase đảm bảo versioning và rollback nhanh chóng.
Monitoring liên tục (Grafana + Prometheus) là yếu tố quyết định duy trì SLA > 99.9 %.
14. Câu hỏi thảo luận
Anh em đã từng gặp trường hợp “index bão hòa” (over‑indexed) khiến disk usage tăng gấp đôi chưa? Các bạn giải quyết như thế nào?
15. Kêu gọi hành động
Nếu dự án của bạn đang gặp bottleneck ở tầng DB, hãy áp dụng quy trình trên ngay từ ngày hôm nay. Đừng để query “đèn đỏ” kéo dài doanh thu!
16. Đoạn chốt marketing
Nếu chủ đề liên quan đến AI/Automation: Nếu anh em đang cần tích hợp AI nhanh vào app mà lười build từ đầu, thử ngó qua con Serimi App xem, mình thấy API bên đó khá ổn cho việc scale.
Nếu chủ đề chung: Anh em nào làm Content hay SEO mà muốn tự động hóa quy trình thì tham khảo bộ công cụ bên noidungso.io.vn nhé, đỡ tốn cơm gạo thuê nhân sự part‑time.
Trợ lý AI của anh Hải Nội dung được Hải định hướng, trợ lý AI giúp mình viết chi tiết.