Advertisement

Tối ưu SQL Server khi bảng dữ liệu trên 10 triệu dòng – Kinh nghiệm thực chiến ERP

Trong quá trình phát triển và vận hành hệ thống ERP, mình gặp rất nhiều trường hợp SQL Server bắt đầu chạy chậm nghiêm trọng khi dữ liệu tăng lên hàng triệu, thậm chí hàng chục triệu dòng.

Ban đầu, mọi thứ vẫn ổn trên môi trường test. Nhưng sau 1–2 năm chạy thực tế, hệ thống bắt đầu xuất hiện:

  1. Query báo cáo chạy 30–60 giây
  2. Màn hình ERP load chậm giờ cao điểm
  3. CPU SQL Server luôn trên 80%
  4. Người dùng than phiền liên tục

Nếu bạn đang làm ERP, phần mềm quản lý doanh nghiệp, hoặc đơn giản là đang xử lý bảng dữ liệu lớn trong SQL Server, thì bài viết này sẽ giúp bạn hiểu đúng bản chất vấn đềtối ưu hiệu quả, dựa trên kinh nghiệm thực tế, không phải lý thuyết suông.


🔹 Vì sao SQL Server chậm khi bảng > 10 triệu dòng?

Rất nhiều lập trình viên nghĩ rằng:

“Máy chủ yếu”
“SQL Server không chịu nổi dữ liệu lớn”

👉 Sai hoàn toàn.

Giao diện chấm công


SQL Server xử lý hàng trăm triệu dòng không có vấn đề, nếu bạn thiết kế và query đúng cách.

Nguyên nhân chậm thường đến từ:

  • Thiết kế bảng ban đầu sai
  • Index tạo không đúng
  • Query viết theo thói quen, không theo Execution Plan
  • ERP dùng chung bảng cho quá nhiều chức năng
  • Thiếu chiến lược phân vùng dữ liệu


🔹 Dấu hiệu hệ thống ERP cần tối ưu SQL gấp

Bạn nên kiểm tra lại ngay nếu gặp các dấu hiệu sau:

  • Cùng 1 query, chạy nhanh trên dev nhưng chậm trên production
  • Query có WHERE nhưng vẫn scan toàn bảng
  • Báo cáo tháng chạy rất lâu
  • Deadlock xuất hiện khi nhiều người dùng
  • CPU SQL Server tăng cao dù user không nhiều


🔹 Nguyên tắc cốt lõi khi tối ưu SQL Server cho ERP

1️⃣ Không bao giờ tối ưu “mù”

Việc đầu tiên KHÔNG phải tạo index.

👉 Việc đầu tiên là xem Execution Plan.

SET STATISTICS IO ON SET STATISTICS TIME ON

Sau đó chạy query cần tối ưu để biết:

  • Có Table Scan hay không
  • Logical Reads bao nhiêu
  • Query tốn thời gian ở bước nào


🔹 Index – Con dao hai lưỡi trong ERP

❌ Sai lầm phổ biến

  • Tạo index cho mọi cột
  • Tạo index nhưng không dùng
  • Không dùng INCLUDE

✅ Cách tạo index hiệu quả

Ví dụ bảng CCGioCong có hơn 10 triệu dòng:

CREATE NONCLUSTERED INDEX IX_CCGioCong_NgayNhanVien ON CCGioCong (NgayCong, MaNhanVien) INCLUDE (SoGio, TangCa)

👉 Index này giúp:

  • Query theo ngày + nhân viên cực nhanh
  • Không cần lookup lại bảng gốc


🔹 Tránh SELECT * – Sai lầm chí mạng

Trong ERP, rất nhiều màn hình chỉ hiển thị 5–6 cột, nhưng code lại:

SELECT * FROM CCGioCong WHERE NgayCong BETWEEN '2025-01-01' AND '2025-01-31'

❌ Điều này làm:

  • Tăng IO
  • Không tận dụng được index
  • Load thừa dữ liệu

✅ Viết đúng:

SELECT MaNhanVien, NgayCong, SoGio FROM CCGioCong WHERE NgayCong BETWEEN '2025-01-01' AND '2025-01-31'

🔹 Tránh hàm trong WHERE

❌ Query khiến SQL Server bỏ index

WHERE YEAR(NgayCong) = 2025

✅ Viết đúng cách

WHERE NgayCong >= '2025-01-01' AND NgayCong < '2026-01-01'

👉 Đây là lỗi rất phổ biến trong ERP, nhất là báo cáo.


🔹 Tách bảng ERP theo chức năng

Một sai lầm mình gặp rất nhiều:

Dùng 1 bảng duy nhất cho:

  • Dữ liệu hiện tại
  • Lịch sử
  • Báo cáo

👉 Sau vài năm, bảng phình to và mọi thứ đều chậm.

Giải pháp thực tế:

  • Bảng *_Current → dữ liệu đang dùng
  • Bảng *_History → dữ liệu cũ
  • Báo cáo chỉ đọc bảng lịch sử


🔹 Case thực tế: Giảm query từ 45s xuống 2s

Trước tối ưu:

  • Bảng: 12 triệu dòng
  • Query báo cáo tháng: ~45 giây
  • CPU SQL Server: ~90%

Sau tối ưu:

  • Thêm index đúng
  • Viết lại WHERE
  • Bỏ SELECT *
  • Tách bảng lịch sử

👉 Kết quả:

  • Query còn ~2 giây
  • CPU ổn định ~40%
  • Người dùng không còn than phiền


🔹 Những lỗi tối ưu SQL ERP thường gặp

  • Tạo index nhưng không kiểm tra Execution Plan
  • Dùng NVARCHAR(MAX) không cần thiết
  • Join nhiều bảng nhưng không có index join
  • Không kiểm soát query động
  • Đổ lỗi cho server thay vì code


🔹 Kết luận

SQL Server không hề yếu, vấn đề nằm ở:

  • Cách thiết kế
  • Cách query
  • Cách vận hành hệ thống ERP

Nếu bạn đang làm ERP, phần mềm doanh nghiệp, hãy nhớ:

Tối ưu SQL đúng cách sẽ giúp hệ thống chạy ổn định nhiều năm mà không cần nâng server.


🔹 FAQ – Câu hỏi thường gặp

❓ Bảng bao nhiêu dòng thì cần tối ưu?
👉 Từ vài trăm nghìn dòng đã nên nghĩ đến index.

❓ Có nên dùng Auto Index?
👉 Không. ERP cần kiểm soát index thủ công.

❓ Khi nào cần partition table?
👉 Khi bảng > 50 triệu dòng hoặc báo cáo rất nặng.

Post a Comment

0 Comments