Không có index thì muốn tìm các dòng thỏa điều kiện, DB phải đọc toàn bộ bảng (full scan).
Vì sao Tính năng mới được triển khai, kèm truy vấn theo điều kiện không có index → Dẫn đến Quét toàn bộ hàng triệu dòng, một query mất từ vài trăm ms đến vài giây → Trên màn hình Hộp thư và lịch sử giao dịch tải chậm, kết nối DB bị giữ khiến các yêu cầu khác cũng phải chờ
Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)
Việc cần làm (Đội phát triển game)
Xem xét kế hoạch thực thi của query mới trước khi triển khai, thêm index, kiểm tra cả query sửa dữ liệu (UPDATE, DELETE) có dùng index không.
Việc cần làm (Đội hạ tầng)
Theo dõi slow query log, tìm query full scan và chia sẻ cho đội phát triển game, khi đang vận hành thì thêm index theo cách online để thời gian khóa ngắn.
Con số tham khảo
Có index thì mất vài ms; không có thì chậm dần theo kích thước dữ liệu, với bảng lớn có thể chậm gấp vài trăm đến vài chục nghìn lần.
Trên đồ thị
Tăng như bậc thang từ một thời điểm · Độ trễ query DB, số dòng đã đọc
Chỗ cần xem
MySQL: xem Rows_examined, Rows_sent trong slow query log (bật log_queries_not_using_indexes thì cả query không dùng index cũng được ghi), SUM_NO_INDEX_USED, SUM_ROWS_EXAMINED trong performance_schema events_statements_summary_by_digest, rồi chạy EXPLAIN. PostgreSQL: xem seq_scan, seq_tup_read trong pg_stat_user_tables, rồi chạy EXPLAIN
Đúng nếu
query mới xuất hiện sau khi triển khai đọc số dòng (Rows_examined) nhiều gấp hàng nghìn lần số dòng trả về (Rows_sent), EXPLAIN cho thấy quét toàn bộ bảng (MySQL type ALL, PostgreSQL Seq Scan). seq_tup_read của bảng lớn tăng dốc kể từ lúc triển khai
Loại trừ nếu
có dùng index mà vẫn chậm → chờ khóa (db-hot-row, db-ddl-lock) hoặc kế hoạch thực thi thay đổi (db-plan-flip). Quét toàn bộ bảng nhỏ có thể là bình thường
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
Tìm hiểu thêm
Không chỉ việc đọc bị chậm. Tùy DB, query sửa dữ liệu (UPDATE, DELETE) chạy không có index có thể khóa cả những dòng đã quét qua, chặn luôn việc lưu dữ liệu của những người chơi không liên quan.
Nguồn
How MySQL Uses IndexesMySQL Không có index thì phải đọc toàn bộ bảng từ dòng đầu tiên, bảng càng lớn chi phí càng cao
The Slow Query LogMySQL Ghi các query vượt long_query_time (mặc định 10 giây), có thể ghi riêng cả các query không dùng index
CREATE INDEX (PostgreSQL Documentation)PostgreSQL Tạo bằng CONCURRENTLY thì tạo được index mà không chặn thao tác ghi, cách tạo thông thường chặn ghi cho đến khi xong
Statement Summary TablesMySQL events_statements_summary_by_digest: SUM_NO_INDEX_USED (số lần chạy không dùng index) và SUM_ROWS_EXAMINED theo từng dạng query
EXPLAIN Output FormatMySQL type là ALL nghĩa là quét toàn bộ bảng, thường tránh bằng cách thêm index