1️⃣ Bối cảnh vấn đề
Trong quá trình vận hành hệ thống SAP, team mình gặp phải vấn đề nghiêm trọng về performance khi user thực hiện tạo billing type là Credit Memo bằng transaction VF01. Khi user tạo Credit Memo, hệ thống tiêu tốn gần như toàn bộ process update, khiến các transaction khác không còn đủ tài nguyên để thực hiện cập nhật dữ liệu.
Hình 1: Process update bị treo khi user tạo billing Credit Memo bằng VF01 |
Nguyên nhân:
Điều tra log và code cho thấy trong EXIT_SAPLVEDF_002 (include ZXEDFU02
), hệ thống có logic tạo output IDoc hóa đơn. Riêng với Credit Memo, đoạn code này thực hiện INNER JOIN giữa hai bảng lớn:
-
VBRK (
3656489
entries) -
VBRP (
44817288
entries)
Việc INNER JOIN trên PRD với volume dữ liệu lớn như vậy khiến truy vấn bị chậm, kéo theo việc tạo Credit Memo mất nhiều thời gian, và khiến các process cập nhật bị treo.
Hình 2: Logic ban đầu join trực tiếp VBRK và VBRP |
2️⃣ Giải pháp ban đầu của vendor
Vendor đã review toàn bộ code trong user exit và sửa lại câu lệnh SQL để tránh dùng INNER JOIN trực tiếp. Giải pháp tạm thời:
-
Tách truy vấn JOIN thành nhiều truy vấn đơn lẻ:
1. Lấy số Sales Order (SO) gốc qua bảng VBAP
2. Lấy số billing gốc từ VBRP
3. Lấy số VAT gốc từ VBRK
Tuy nhiên, cách tách này chỉ cải thiện tốc độ ~3.8 lần vì phần 2 (lấy billing gốc từ VBRP không theo key chính) vẫn scan dữ liệu lớn, chưa thực sự tối ưu.
Hình 3: Logic vendor lấy dữ liệu từ ba bảng VPAP, VBRP, VBRK |
3️⃣ Giải pháp tối ưu triệt để
Dựa trên kinh nghiệm xử lý SQL và hiểu rõ quan hệ giữa các bảng (VBFA, VBRK, VBRP), mình đã thiết kế lại truy vấn:
- Không JOIN trực tiếp hai bảng lớn
- Tận dụng primary key và foreign key chuẩn của SAP
- Bổ sung logic để lấy thêm SO item của SO gốc, đảm bảo dữ liệu đầy đủ và đúng nghiệp vụ.
Cách mình làm:
1. Lấy số Sales Order (SO) gốc qua bảng VBAP => giữ nguyên logic nhưng lấy thêm SO item gốc
2. Lấy số billing gốc từ
VBRP=> lấy từ bảng VBFA dựa vào SO & SO item và là key chính3. Lấy số VAT gốc từ VBRK => giữ nguyên
Nhờ đó, toàn bộ quá trình lấy dữ liệu gần như tức thì, không còn bottleneck.
Hình 4: Giải pháp của mình lấy dữ liệu từ VBAP, VBFA, VBRK |
4️⃣ Kết quả so sánh
Giai đoạn | Tổng thời gian (Microseconds) | Thời gian (Minutes) |
---|---|---|
Before | 297,094,410 | 4.95 phút |
After 1 (Vendor) | 78,196,851 | 1.30 phút (~3.8x nhanh hơn) |
After 2 (Tối ưu triệt để) | Gần như bằng 0 |
5️⃣ Bài học kinh nghiệm
- Hiểu rõ nghiệp vụ & data structure: là điều tiên quyết khi tối ưu SQL trong SAP.
- Hạn chế JOIN trực tiếp các bảng lớn, đặc biệt khi dữ liệu tăng trưởng liên tục.
- Tinh thần học hỏi và thử nghiệm sẽ giúp bạn giải quyết được các bottleneck khó nhằn nhất.
🎯Kết luận
Việc xử lý thành công issue này là minh chứng rằng chỉ cần hiểu đúng dữ liệu và logic nghiệp vụ, bạn hoàn toàn có thể tối ưu hệ thống SAP một cách hiệu quả mà không phụ thuộc hoàn toàn vào vendor.
Mình tự hào khi đã đóng góp giải pháp thực tế, giúp hệ thống vận hành ổn định hơn.
Mong rằng chia sẻ này sẽ hữu ích cho các bạn đang làm SAP ABAP, Basis, hay tư vấn module có liên quan đến billing & output IDoc.
Bạn đã từng gặp tình huống tương tự? Chia sẻ thêm kinh nghiệm tối ưu SAP của bạn nhé!
0 Comments