Tối ưu SQL Queries giúp website WordPress nhanh hơn 2026

Tối ưu SQL Queries giúp website WordPress nhanh hơn 2026

Website tải nhanh hơn đồng nghĩa với việc người dùng có trải nghiệm tốt hơn, tỷ lệ thoát trang giảm và hiệu quả SEO cũng được cải thiện rõ rệt. Với các website WordPress, tốc độ không chỉ phụ thuộc vào giao diện, hosting, dịch vụ CDN hay dung lượng hình ảnh, mà còn chịu ảnh hưởng trực tiếp từ cách hệ thống truy vấn dữ liệu trong database.

Thực tế, một website WordPress có thể đã được tối ưu ảnh, cài cache, dùng CDN và nâng cấp server nhưng vẫn chậm. Nguyên nhân có thể đến từ một yếu tố ít được chú ý hơn: SQL Queries.

Với các website dynamic database-driven như WordPress, WooCommerce, website tin tức, blog nhiều bài viết hoặc hệ thống có nhiều plugin, truy vấn database có khả năng trở thành điểm nghẽn lớn nhất khiến trang tải chậm.

Trong bài viết dưới đây, Bizfly Cloud sẽ cùng bạn tìm hiểu cách xác định các SQL query chậm, phân tích nguyên nhân và áp dụng những phương pháp tối ưu phù hợp trong năm 2026.

SQL Queries là gì và vì sao có thể làm chậm website?

SQL Queries là các câu lệnh được website sử dụng để lấy, thêm, sửa hoặc xóa dữ liệu trong database. Với WordPress, mỗi lần người dùng truy cập một trang, hệ thống có thể phải thực hiện hàng chục, thậm chí hàng trăm truy vấn để lấy nội dung bài viết, menu, chuyên mục, thông tin người dùng, sản phẩm, đơn hàng, plugin, theme và nhiều dữ liệu liên quan khác.

Nếu các truy vấn này được viết chưa tối ưu, gọi lặp lại quá nhiều lần hoặc phải quét dữ liệu trên bảng lớn, website sẽ mất nhiều thời gian hơn để phản hồi. Khi đó, dù server có cấu hình tốt, thời gian tải trang vẫn có thể bị kéo dài.

Một số nguyên nhân phổ biến khiến SQL Queries làm chậm website gồm:

  • Truy vấn không sử dụng index phù hợp.
  • Bảng dữ liệu quá lớn nhưng vẫn phải full table scan.
  • Plugin hoặc theme tạo ra quá nhiều truy vấn không cần thiết.
  • Query bị gọi lặp lại nhiều lần trong cùng một lần tải trang.
  • Sử dụng JOIN, ORDER BY, GROUP BY hoặc LIKE không tối ưu.
  • Lưu quá nhiều dữ liệu vào wp_postmeta, wp_options hoặc custom post type.
  • Không có Object Cache hoặc cache chưa được thiết lập đúng.

Nói cách khác, tối ưu SQL Queries không chỉ là việc của lập trình viên backend. Đây cũng là một phần quan trọng trong tối ưu hiệu năng website, đặc biệt với các website WordPress có lượng nội dung lớn hoặc traffic tăng nhanh. 

Xác định nguyên nhân khiến truy vấn SQL bị chậm 

Bước đầu tiên cần làm là tìm ra truy vấn nào đang gây vấn đề. Với WordPress, một trong những công cụ phổ biến nhất hiện nay là Query Monitor.

Query Monitor là plugin hỗ trợ debug cho WordPress và WooCommerce. Công cụ này cho phép theo dõi database queries, PHP errors, hooks, actions, REST API, Ajax calls, block themes và nhiều thành phần khác trong quá trình tải trang. Đặc biệt, Query Monitor có thể hiển thị các truy vấn chậm, truy vấn bị lặp, truy vấn lỗi, đồng thời lọc theo plugin, theme, WordPress core hoặc function đang gọi truy vấn đó. 

Nó cho phép bạn filter chúng bằng các đoạn code hoặc component (plugin, theme hoặc WordPress core) đang gọi chúng, và highlight các truy vấn bị trùng lặp và bị chậm:

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 1.

Xác định nguyên nhân khiến truy vấn SQL bị chậm

Điểm hữu ích của Query Monitor là bạn không chỉ biết website đang chạy bao nhiêu truy vấn, mà còn biết truy vấn đó đến từ đâu. Ví dụ, một plugin WooCommerce, một function trong theme hoặc một đoạn code tùy chỉnh có thể đang tạo ra nhiều truy vấn hơn mức cần thiết.

Khi kiểm tra, bạn nên chú ý các thông tin sau:

  • Tổng số query khi tải trang.
  • Query nào mất nhiều thời gian nhất.
  • Query nào bị gọi lặp lại nhiều lần.
  • Component nào tạo ra nhiều truy vấn nhất.
  • Có truy vấn SELECT, UPDATE, DELETE bất thường khi tải trang hay không.
  • Có query lỗi do bảng/cột không tồn tại hoặc cú pháp sai hay không.

Nếu không muốn cài debug plugin trực tiếp trên production, bạn có thể kiểm tra trên staging hoặc bật Slow Query Log ở phía MySQL/MariaDB. Cách này giúp ghi lại các truy vấn mất nhiều thời gian thực thi để đội kỹ thuật phân tích sau. Tuy nhiên, Slow Query Log nên được bật có kiểm soát và tắt đi khi không cần thiết để tránh tạo thêm log không cần thiết cho hệ thống.

Hiểu rõ truy vấn nào đang gây vấn đề 

Sau khi đã xác định được query chậm, bước tiếp theo là hiểu vì sao truy vấn đó chậm. Không phải query nào chạy lâu cũng do server yếu. Nhiều trường hợp, nguyên nhân đến từ cách truy vấn dữ liệu chưa hợp lý. Gần đây trong quá trình phát triển website, chúng tôi đã tìm thấy một truy vấn mất khoảng 8s để thực thi!

Ví dụ, với website WooCommerce, dữ liệu đơn hàng, sản phẩm, người dùng, subscription hoặc license có thể nằm ở nhiều bảng khác nhau. Một truy vấn lấy thông tin khách hàng có thể phải JOIN qua nhiều bảng như wp_posts, wp_postmeta, bảng order, bảng license hoặc bảng tùy chỉnh của plugin.

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 2.

Ví dụ về truy vấn

Nếu bảng dữ liệu lớn và truy vấn không có index phù hợp, MySQL có thể phải đọc toàn bộ bảng để tìm dữ liệu cần thiết. Đây là tình trạng thường được gọi là full table scan.

Full table scan không phải lúc nào cũng xấu, nhưng với các bảng lớn, nó có thể khiến truy vấn chậm đáng kể. Đặc biệt, những bảng như wp_postmeta, wp_options, bảng log, bảng order hoặc custom table có hàng trăm nghìn đến hàng triệu dòng sẽ dễ trở thành điểm nghẽn nếu không được tối ưu đúng cách.

Sử dụng EXPLAIN để phân tích SQL Query 

MySQL có một câu lệnh khá tiên dụng đó là DESCRIBE, có thể được sử dụng để đưa ra thông tin về cấu trúc của một bảng như các cột, kiểu dữ liệu, các giá trị mặc định. Vì vậy, nếu bạn thực thi DESCRIBE wp_postmeta, kết quả sẽ như sau:

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 3.

Có thể bạn đã biết về lệnh này. Nhưng bạn có biết rằng DESCRIBE thực sự có thể được sử dụng trên các câu lệnh SELECT, INSERT, UPDATE, REPLACE và DELETE không? Bởi đồng nghĩa của nó là EXPLAIN và nó sẽ cung cấp cho chúng ta thông tin chi tiết về cách statement sẽ được execute.

Đây là kết quả cho truy vấn chậm:

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 4.

Thoạt nhìn thì bảng này có thể không dễ hiểu lắm cho lắm.

Cột (column) quan trọng nhất là type, mô tả cách các bảng được kết hợp với nhau. Nếu All, có nghĩa là MySQL đang đọc toàn bộ bảng từ disk, tăng tỷ lệ I/O và đặt tải trên CPU. Điều này được biết đến như là "full table scan".

Rows (dòng): cũng là một dấu hiệu về những gì MySQL đang phải làm, nó được thể hiện bằng việc có bao nhiêu rows được tìm thấy trong kết quả của truy vấn.

Explain cung cấp thông tin để có thể sử dụng trong việc tối ưu hóa. Ví dụ, bảng pm2 (wp_postmeta) cho biết chúng ta đang sử dụng filesort, vì chúng ta đang yêu cầu các kết quả được sắp xếp với ORDER BY trên câu query. Nếu nhóm các truy vấn thì chúng ta sẽ cần bổ sung thêm chi phí cho việc thực hiện.

Điều tra trực quan

MySQL Workbench là một công cụ miễn phí, khá hữu ích cho kiểu điều tra này. Đối với các database chạy trên MySQL 5.6 trở lên, kết quả của EXPLAIN có thể được xuất ra dưới dạng JSON và MySQL Workbench, biến JSON thành một kế hoạch thực hiện trực quan của statement:

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 5.

Nó sẽ tự động chỉ ra vấn đề của bạn bằng cách tô màu các phần của query. Chúng ta có thể thấy ngay rằng việc join vào bảng wp_woocommerce_software_licences (alias l) có một vấn đề nghiêm trọng.

Giải quyết

Một phần của truy vấn đang thực hiện việc full table scan, bạn nên cố gắng tránh điều này vì nó sử dụng một non-indexed column là order_id trong việc join giữa bảng wp_woocommerce_software_licences với bảng wp_posts. Đây là vấn đề thường gặp đối với các truy vấn chậm và có thể được giải quyết một cách dễ dàng.

Index trong MySQL

order_id là một phần khá quan trọng trong việc xác định dữ liệu trong bảng, nếu chúng ta đang truy vấn như thế này, chúng ta thực sự cần có index trên column, nếu không thì MySQL sẽ quét từng row của bảng cho đến khi nó tìm thấy các row cần thiết. Hãy thêm index và xem điều gì sẽ xảy ra: 

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 6.

Vậy là chúng ta đã giảm hơn 5s truy vấn bằng cách thêm index đó.

Tìm hiểu về Query

Kiểm tra truy vấn - join by join, subquery by subquery có làm những việc không cần thiết không? Việc tối ưu hóa có thể được thực hiện không?

Trong trường hợp này, chúng ta join bảng licenses và bảng posts sử dụng order_id, hạn chế đăng các loại shop_order. Điều này giúp toàn vẹn dữ liệu, hơn nữa giúp đảm bảo rằng chúng ta chỉ đang sử dụng các bản ghi với thứ tự chính xác, tuy nhiên, nó thực sự là một phần thừa của truy vấn. Hãy xóa và xem điều đó có cải thiện mọi thứ không: 

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 7.

Tuy không cải thiện được nhiều nhưng cũng giúp query thực hiện dưới 3s.

Cache 

Nếu server của bạn không có MySQL query caching theo mặc định, MySQL sẽ lưu giữ một record lưu lại tất cả các câu lệnh được thực hiện cùng với kết quả, và nếu một câu lệnh giống hệt nhau được thực hiện thì các kết quả được lưu trong cache sẽ được trả về. Bộ nhớ cache sẽ không bị lỗi thời, vì MySQL xóa cache khi các bảng được thay đổi.

Query Monitor đã tìm thấy một truy vấn chạy 4 lần trên một lần tải trang của chúng tôi, mặc dù có bộ nhớ cache truy vấn MySQL, nhưng đọc trùng lặp cơ sở dữ liệu trong một yêu cầu thực sự nên tránh. Bộ nhớ đệm tĩnh trong mã PHP là một cách đơn giản và hiệu quả để giải quyết vấn đề này. Về cơ bản bạn đang tìm nạp các kết quả của một truy vấn từ cơ sở dữ liệu trong lần đầu tiên nó được yêu cầu, và lưu chúng trong thuộc tính tĩnh của một lớp, sau đó các cuộc gọi tiếp theo sẽ được trả về kết quả từ thuộc tính tĩnh:

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 8.

Nếu bạn đang xem xét các kết quả của truy vấn trên các yêu cầu, thì bạn sẽ cần thực hiện một persistent Cache Object. Tuy nhiên, code của bạn sẽ cần phải có trách nhiệm setting cache và loại bỏ khả năng cache entry khi dữ liệu cơ bản thay đổi.

Mạnh dạn thử nghiệm những phương pháp khác

Có những cách tiếp cận khác mà chúng ta có thể thực hiện để thử và tăng tốc độ độ thực thi truy vấn nhiều hơn một chút so với việc chỉ chỉnh sửa truy vấn hoặc thêm chỉ mục. Một trong những phần chậm nhất của truy vấn là việc join các bảng từ customer id đến product id, và chúng ta phải thực hiện việc này cho mọi customer. Điều gì sẽ xảy ra nếu chúng ta chỉ join một lần, từ đó chúng ta có thể lấy dữ liệu của customer khi cần?

Bạn có thể chuẩn hóa dữ liệu bằng cách tạo bảng để lưu trữ "license data", cùng với user id và product id cho tất cả các license, và chỉ truy vấn đối với một customer cụ thể. Bạn sẽ cần phải xây dựng lại bảng bằng cách sử dụng các MySQL trigger trên INSERT / UPDATE / DELETE vào các license table (hoặc những bảng khác tùy thuộc vào cách dữ liệu có thể thay đổi), điều này sẽ cải thiện hiệu suất truy vấn dữ liệu đó.

Tương tự, nếu một số join trong MySQL làm chậm truy vấn của bạn, có thể ngắt truy vấn thành hai hoặc nhiều câu lệnh và thực thi chúng một cách riêng biệt trong PHP, sau đó thu thập và filter kết quả trong code. Laravel cũng làm một điều tương tự là eager loading các relation trong Eloquent.

WordPress có thể dễ bị truy vấn chậm hơn trên wp_posts table, nếu như bạn có một lượng lớn dữ liệu và nhiều loại bài đăng dạng tùy biến khác nhau. Nếu bạn đang tìm kiếm các truy vấn bị chậm đó, thì hãy xem xét di chuyển ra khỏi mô hình lưu trữ loại custom post và custom table.

Kết luận

Tối ưu SQL Queries giúp website nhanh hơn - Ảnh 9.

Với các phương pháp tối ưu hóa truy vấn này, chúng ta đã làm các truy vấn giảm từ 8s xuống còn hơn 2s và giảm số lần được gọi từ 4 xuống còn 1. 

Lưu ý, thời gian truy vấn được ghi lại khi chạy trên môi trường develop và sẽ nhanh hơn trên production.

Hy vọng đây là một hướng dẫn hữu ích giúp bạn theo dõi các truy vấn chậm và sửa chúng. Tối ưu hóa truy vấn có vẻ giống như một nhiệm vụ đáng sợ, nhưng ngay sau khi bạn thử và thành công, bạn sẽ bắt đầu nhận được bug và muốn cải thiện mọi thứ hơn nữa.

Theo viblo.vn

>> Có thể bạn quan tâm: Lợi ích của CDN mang lại cho doanh nghiệp phổ biến hiện nay

SHARE
Zalo