Mục lục

Bạn đã từng nghe về các truy vấn N+1 chưa? Nếu chưa, đừng lo lắng - đây là một vấn đề phổ biến trong phát triển web, nhưng chúng ta có một công cụ hữu ích để giúp xác định và giải quyết nó. Hãy nói về gem bullet https://github.com/flyerhzm/bullet!

Thay vì chỉ giám sát các truy vấn, Bullet hoạt động như một người bảo vệ cảnh giác, xem xét kỹ lưỡng mã của bạn để tìm ra các điểm nghẽn hiệu suất. Nó xác định các khu vực cần cải thiện bằng cách đánh dấu các vấn đề truy vấn N+1, eager loading không cần thiết, và đề xuất sử dụng bộ đếm cache.

Truy vấn N+1 là gì?

Hãy tưởng tượng việc viết thư cho tất cả bạn cùng lớp và hỏi về cuốn sách yêu thích của họ. Bạn có thể làm điều này:

  • Lấy danh sách tất cả bạn cùng lớp
  • Hỏi từng bạn về cuốn sách yêu thích của họ

Đây giống như một truy vấn N+1. Bạn thực hiện một yêu cầu để lấy danh sách (1), sau đó một yêu cầu cho mỗi bạn cùng lớp (N). Nếu bạn có 30 bạn cùng lớp, đó là 31 yêu cầu! Đó là rất nhiều công việc và có thể làm chậm trang web của bạn.

Thêm gem bullet vào dự án của bạn

Gem bullet giống như một robot thân thiện xem xét trang web của bạn và cho bạn biết khi bạn đã thực hiện quá nhiều yêu cầu với N+1. Nó rất dễ sử dụng:

  • Thêm nó vào dự án của bạn
  • Sử dụng trang web của bạn như bình thường
  • Bullet sẽ cho bạn biết khi nó thấy các truy vấn N+1

Cách thực hành tốt nhất là sử dụng Bullet trong chế độ phát triển hoặc chế độ tùy chỉnh (staging, profile, v.v.). Để biết thêm thông tin, hãy truy cập https://github.com/flyerhzm/bullet.

Cách khắc phục các truy vấn N+1

Khi bullet chỉ ra một vấn đề, bạn có thể sửa nó. Thay vì hỏi từng bạn cùng lớp riêng lẻ, bạn có thể hỏi tất cả cùng một lúc, "Này các bạn, cuốn sách yêu thích của các bạn là gì?" Điều này nhanh hơn nhiều!

Hãy phân tích tại sao việc hỏi mọi người cùng một lúc lại nhanh hơn:

  • Ít chuyến đi hơn: Khi bạn hỏi từng bạn cùng lớp riêng lẻ, bạn đang thực hiện nhiều chuyến đi riêng biệt (một cho mỗi học sinh). Nhưng khi bạn hỏi cả lớp cùng một lúc, bạn chỉ thực hiện một chuyến đi.
  • Tiết kiệm thời gian: Hãy nghĩ về nó như việc giao thư. Nếu bạn phải đến từng nhà trên một con phố một cách riêng lẻ, sẽ mất nhiều thời gian hơn so với việc bạn có thể hét lên thông điệp của mình cho cả con phố cùng một lúc.
  • Hiệu quả mạng: Trong thuật ngữ máy tính, mỗi "hỏi" giống như gửi một tin nhắn qua mạng. Gửi nhiều tin nhắn nhỏ (một cho mỗi học sinh) kém hiệu quả hơn việc gửi một tin nhắn lớn hơn (cho cả lớp).
  • Thời gian xử lý: Máy tính (hoặc cơ sở dữ liệu) của bạn thường có thể xử lý một yêu cầu lớn hơn hiệu quả hơn so với nhiều yêu cầu nhỏ. Nó giống như giải một bài toán lớn so với nhiều bài toán nhỏ - bài toán lớn có vẻ đáng sợ, nhưng thường nhanh hơn việc giải nhiều bài toán nhỏ.
  • Giảm chi phí phụ trợ: Mỗi truy vấn riêng lẻ đi kèm với một số công việc phụ trợ (gọi là overhead). Bằng cách thực hiện một truy vấn lớn hơn, bạn chỉ có công việc phụ trợ này một lần, không phải cho mỗi học sinh.

Trong thuật ngữ cơ sở dữ liệu, cách tiếp cận này để lấy tất cả thông tin cùng một lúc được gọi là "eager loading". Nó giống như việc lấp đầy toàn bộ ba lô của bạn với sách trong một lần, thay vì đi đi lại lại từ tủ cho mỗi lớp học.

Từ góc độ lập trình, chúng ta sử dụng các đối tượng "eager loading" hoặc "includes" để lấy tất cả thông tin chúng ta cần cùng một lúc.

Tại sao bạn nên quan tâm?

Ngăn chặn các truy vấn N+1 có thể tăng tốc đáng kể trang web của bạn. Các trang web nhanh hơn giúp người dùng hài lòng, sử dụng ít năng lượng hơn, và thậm chí có thể xếp hạng cao hơn trong các công cụ tìm kiếm.

Hãy nhớ rằng việc viết mã hiệu quả là một kỹ năng quan trọng đối với bất kỳ nhà phát triển nào. Các công cụ như gem bullet giúp chúng ta học hỏi và cải thiện mã của mình.

Xin chào! Cám ơn bạn đã đọc bài viết có tiêu đề Ngăn chặn sự chậm trễ của trang web: Xác định và khắc phục các truy vấn N+1 bằng gem Bullet của tác giả Vũ Lê Huân. Trong trường hợp bạn muốn tìm hiểu thêm thông tin về tác giả, bạn có thể truy cập .