Đọc benchmark: phép đo nào chống lưng cho kết luận?
Câu hỏi: một bảng import nhanh hơn có đủ để hứa thời gian cho 10 triệu hàng không?
Cần biết trước: lab import CSV và mean/min/max. Bài dùng số đo của lab đó, lấy lần chạy 2026-10-03 07:21:54 UTC. Bài import là nơi giữ toàn bộ fixture, bảng và cách tái lập; ở đây chỉ trích bốn dòng để đọc kết luận. Không chạy lại benchmark mới và không có số đo 10 triệu hàng.
Đọc provenance trước thứ hạng
| Thành phần | Bằng chứng của phép đo này | Điều chưa biết |
|---|---|---|
| Máy | macOS/Darwin arm64, 10 logical CPU | Model chip, RAM, loại ổ đĩa, tải nền chưa lưu trong raw metadata; không tự điền |
| Runtime | Python 3.14.4, PostgreSQL 18.6 native/socket local | Không container, MySQL hoặc remote network |
| Dataset | CSV sinh seed17, 1000/5000/10000 hàng, batch400; input hash và export theo ID khớp | Không kích thước/ phân bố production hoặc file10M |
| Correctness | Một transaction/file; PK/FK/CHECK/index, fsync/full_page_writes/synchronous_commit bật | Không tắt durability để so tốc độ; chưa đo external side effect |
| Timer | CSV đọc/serialize, khởi tạo psql, protocol và commit | Reset/seed/validation ngoài timer; không phải riêng thời gian SQL server |
| Cache/lượt | Warm-up, không eviction; ba lượt/method/size, xoay thứ tự; 27 sample | Chưa cold cache/reboot, chưa nhiều máy hoặc confidence interval đáng tin |
Nói “đã warm-up” không chứng minh mọi page đều trong RAM. Xóa bảng không phải
xóa OS cache; restart một client không phải cold DB. Khi người nhận cần startup
latency, giữ startup trong timer; nếu loại nó, phải báo riêng và giải thích boundary.
Clock elapsed dùng perf_counter, chỉ lấy hiệu hai mốc; UTC là provenance chứ
không phải clock đo duration. Python clock.
Mean nhỏ hơn, nhưng mẫu có chồng nhau không?
Thời gian dưới tính bằng giây, làm tròn sáu chữ số; stdev là sample standard deviation của ba lượt. Nó không phải khoảng tin cậy, sai số timer hoặc p99 latency. Python statistics.
| Hàng | Method | Mean s | Min s | Max s | Sample stdev s |
|---|---|---|---|---|---|
| 1000 | batch | 0.014548 | 0.013935 | 0.015769 | 0.001058 |
| 1000 | copy | 0.014162 | 0.013496 | 0.014676 | 0.000605 |
| 10000 | batch | 0.049266 | 0.047273 | 0.052186 | 0.002584 |
| 10000 | copy | 0.037493 | 0.037410 | 0.037620 | 0.000112 |
Ở 1000 hàng, range batch/COPY chồng nhau; mean COPY thấp hơn không đủ để kết luận mọi lượt luôn thắng. Ở 10000 hàng, ba sample COPY thấp hơn ba sample batch trong lần đo này. Range không chồng nhau vẫn chưa chứng minh thắng ở máy khác, workload khác hoặc cùng máy ngày khác. Không tính p99 từ ba sample rồi đặt SLO production.
Row→batch→COPY thay cả serialization, cách gửi SQL/protocol và client processing. Giữ input và transaction giúp so tổng đường đi, chưa cô lập riêng network RTT, parser hay lock contention. Muốn gán nguyên nhân, thêm đo từng tầng hoặc chỉ đổi một biến với cùng semantics; dùng debug có giả thuyết.
Ngoại suy 10M: phép tính đúng vẫn có thể trả lời sai câu hỏi
Ví dụ giả định, chưa đo: nhân mean COPY ở 10000 hàng với tỷ lệ 1000 để tưởng
tượng 10000000 hàng: 0.037493 × 1000 = 37.493 giây (dùng mean đã làm tròn).
Đây là phép nhân minh họa, không phải thời gian đã chạy, hồi quy hoặc cam kết.
Nó nhân cả startup cố định lên 1000 lần, trong khi một file lớn chỉ startup một lần; đồng thời bỏ qua WAL/checkpoint, cache capacity, index growth, CSV memory và tải đồng thời có thể làm chi phí mỗi hàng tăng. Hai sai lệch có thể trái chiều, nên không biết ngoại suy đang cao hay thấp. Một đường fit trông đẹp trong mẫu nhỏ không kiểm được regime chưa chạy; cần sample lớn hơn, residual/holdout và workload đại diện.
Không dùng tốc độ trung bình của import một transaction để sizing online requests. Latency, lỗi, lock và deadline của request khác boundary. Xem scale database để chọn phép đo đúng nút thắt.
Viết headline mà dữ liệu chịu được
| Claim | Vì sao |
|---|---|
| Sai: “COPY luôn nhanh nhất và import10M chỉ mất37.493s” | Đổi ngoại suy thành đo thật, xóa overlap và mọi giới hạn môi trường |
| Đúng: “Trong ba lượt local PG18.6 với10000 hàng, COPY mean0.037493s, batch mean0.049266s” | Ghi workload, repeat, runtime và statistic; phải kèm timer/cache/correctness ở trên |
Checklist trước khi tin hoặc chia sẻ
- Output có đúng toàn dữ liệu và lỗi không bị bỏ qua? Constraint/durability có tương đương?
- Dataset/seed/hash, schema/index, runtime và máy có đủ để tái lập? Metadata thiếu phải ghi thiếu.
- Timer bắt đầu/kết thúc ở đâu; startup, parse, network, commit, validation phần nào được tính?
- Warm/cold được tạo bằng cách nào, thứ tự chạy có thiên lệch, bao nhiêu lượt và biến thiên?
- Mỗi kết luận đang dùng số đo, giả định, dự báo hay suy đoán nguyên nhân? Có sample ở quy mô claim?
- Có raw samples để tính lại, điều kiện dừng và phép thử bác bỏ? Kết quả lỗi/timeout có cùng được báo?
Tái lập bằng lab import ở đầu bài sẽ tạo bulk-results.json mới; giữ kết quả mới với
môi trường của bạn, không thay raw gốc bằng lượt tình cờ nhanh hơn. Bài này chứng
minh cách đọc một phép đo hữu hạn; lựa chọn production vẫn cần đo workload của bạn.