Vụ án chỉ mục cơ sở dữ liệu bị mất

By ducpm, at: 16:25 Ngày 29 tháng 10 năm 2025

Thời gian đọc ước tính: __READING_TIME__ phút

The Case of the Missing Database Index
The Case of the Missing Database Index

 

Giới thiệu

 

Ứng dụng Django của bạn chạy mượt mà trong quá trình phát triển. Các truy vấn trả về ngay lập tức. Nhưng trong môi trường sản xuất, mọi thứ chậm lại đáng kể. Trang web mất vài giây để tải, người dùng phàn nàn và sử dụng CPU tăng đột biến.

 

Nguyên nhân? Một chỉ mục cơ sở dữ liệu bị thiếu - một kẻ giết người hiệu năng vô hình ẩn giấu cho đến khi lưu lượng truy cập tăng lên. Tại Glinteco, chúng tôi đã thấy điều này vô số lần: các ứng dụng có số lượng người dùng tăng nhưng thiết kế cơ sở dữ liệu không.

 

Bối cảnh: Truy vấn chậm

 

Một truy vấn đơn giản như thế này chạy trong vài mili giây trong môi trường phát triển:

 

BlogPost.objects.filter(author_id=42).order_by('-created_at')

 

Nhưng trong môi trường sản xuất, với hàng triệu hàng, cùng một truy vấn mất nhiều giây. Cơ sở dữ liệu quét toàn bộ bảng thay vì sử dụng lối tắt.

 

Bằng chứng bị thiếu trong hiện trường vụ án này? Một chỉ mục.

 

Vấn đề xảy ra như thế nào

 

  1. Bộ dữ liệu phát triển nhỏ

     

    • Các cơ sở dữ liệu cục bộ chỉ có vài trăm hàng. Hiệu năng trông ổn
       

  2. Tăng trưởng nhanh chóng trong sản xuất

     

    • Khi số lượng bản ghi tăng lên hàng triệu, các truy vấn chậm lại theo cấp số nhân
       

  3. Không có chiến lược chỉ mục

     

    • Các nhà phát triển dựa vào các giá trị mặc định, quên tối ưu hóa các cột thường được sử dụng trong bộ lọc hoặc nối
       

  4. Sai lầm về việc lập chỉ mục quá mức

     

    • Ngược lại, quá nhiều chỉ mục có thể làm chậm quá trình ghi và lãng phí dung lượng lưu trữ

 

Gỡ lỗi tắc nghẽn

 

Để phát hiện chỉ mục bị thiếu, các nhà phát triển sử dụng các công cụ cơ sở dữ liệu:

 

 

Tài liệu của PostgreSQL cung cấp hướng dẫn chi tiết về việc đọc kế hoạch truy vấn.

 

Khắc phục

 

Thêm chỉ mục vào các bộ lọc phổ biến

 

Ví dụ
 

CREATE INDEX idx_blogpost_author ON blogpost (author_id);

 

Sử dụng db_index=True của Django

 

author = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True)

 

Tận dụng Chỉ mục Hợp thành

 

Đối với các truy vấn lọc trên nhiều trường.

 

BlogPost.objects.filter(author_id=42, created_at__gte="2025-01-01")

 

Nếu không có chỉ mục, cơ sở dữ liệu sẽ quét toàn bộ bảng blogpost. Với chỉ mục hợp thành trên (author_id, created_at), cơ sở dữ liệu có thể nhảy trực tiếp đến tập hợp con chính xác.

 

Giải pháp

 

class BlogPost(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        indexes = [
            models.Index(fields=['author', 'created_at']),
        ]

 

Thường xuyên kiểm tra các truy vấn

 

Chạy phân tích truy vấn trong môi trường staging với khối lượng dữ liệu thực tế.

 

Tránh lập chỉ mục quá mức

 

Mỗi chỉ mục làm tăng tốc độ đọc nhưng làm chậm tốc độ ghi. Cần đạt được sự cân bằng.

 

Thông tin thêm có thể được tìm thấy tại đây: https://testdriven.io/blog/django-db-indexing/

 

Bài học kinh nghiệm

 

Chỉ mục cơ sở dữ liệu vô hình khi bị thiếu cho đến khi chúng làm hệ thống của bạn ngừng hoạt động. Trường hợp Chỉ mục Bị Thiếu là lời nhắc nhở rằng hiệu năng không chỉ là về mã, mà còn về thiết kế dữ liệu ở quy mô lớn.

 

Tại Glinteco, chúng tôi giúp khách hàng trên khắp các ngành thiết kế các hệ thống Django và cơ sở dữ liệu có khả năng mở rộng. Cho dù đó là thêm chỉ mục phù hợp, điều chỉnh truy vấn hay xây dựng kế hoạch tăng trưởng dài hạn, chúng tôi đảm bảo ứng dụng của bạn luôn nhanh chóng khi mở rộng.

 

Nếu ứng dụng của bạn cảm thấy chậm chạp và bạn không thể tìm ra nguyên nhân, đó có thể chỉ là một chỉ mục bị thiếu và chúng tôi biết cách tìm ra nó.

 

Tag list:

Theo dõi

Theo dõi bản tin của chúng tôi và không bao giờ bỏ lỡ những tin tức mới nhất.