Khi nào dùng WP_Query?
WP_Query là class mạnh mẽ và linh hoạt nhất trong WordPress. Nó cho phép bạn truy vấn post theo hầu hết tiêu chí (post type, taxonomy, meta, order, paginate…). Tuy nhiên, WP_Query cũng là công cụ “nặng” nhất vì nó xử lý rất nhiều logic nội bộ.
<?php
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 10,
'paged' => get_query_var('paged', 1),
]);
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
the_title('<h2>', '</h2>');
}
wp_reset_postdata();
}
?>
Sử dụng WP_Query khi bạn cần phân trang, query phức tạp với nhiều tham số, hoặc muốn hook vào các filter có sẵn.
Khi nào dùng get_posts?
get_posts() thực chất là một wrapper của WP_Query, nhưng đã bật sẵn vài option tối ưu: no_found_rows = true, update_post_meta_cache = false, update_post_term_cache = false. Nghĩa là nó nhẹ hơn khi bạn chỉ cần danh sách post mà không cần phân trang hoặc tính toán tổng số trang.
<?php
$posts = get_posts([
'post_type' => 'page',
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC',
]);
foreach ( $posts as $post ) {
setup_postdata($post);
echo '<h3>' . esc_html( get_the_title($post) ) . '</h3>';
}
wp_reset_postdata();
?>
Sử dụng get_posts() khi chỉ cần lấy một số lượng nhỏ post, không phân trang, không cần tính tổng số trang.
Khi nào dùng $wpdb?
$wpdb cho phép bạn chạy query SQL trực tiếp trên database. Đây là cách nhanh nhất, nhưng cũng dễ sai và bỏ qua nhiều layer bảo mật, cache của WordPress. Dùng khi bạn cần query đặc biệt mà WP_Query không đáp ứng, hoặc khi cần join nhiều bảng.
<?php
global $wpdb;
$results = $wpdb->get_results( $wpdb->prepare(
"SELECT ID, post_title FROM {$wpdb->posts}
WHERE post_type = %s AND post_status = %s
ORDER BY post_date DESC
LIMIT %d",
'post', 'publish', 5
) );
foreach ( $results as $row ) {
echo '<p>' . esc_html( $row->post_title ) . '</p>';
}
?>
Sử dụng $wpdb khi bạn cần hiệu năng cao, join dữ liệu phức tạp, hoặc báo cáo tổng hợp. Luôn nhớ dùng $wpdb->prepare() để tránh SQL injection.
So sánh hiệu năng: WP_Query vs get_posts vs $wpdb
| Phương pháp | Hiệu năng | Khi nên dùng | Khi tránh dùng |
|---|---|---|---|
WP_Query |
Chậm nhất (nhiều layer xử lý) | Phân trang, query phức tạp | Lấy danh sách nhẹ, không paginate |
get_posts |
Nhanh hơn WP_Query | Lấy ít post, không cần found rows | Lúc cần template tag multi-loop |
$wpdb |
Nhanh nhất | Join bảng, báo cáo, logic đặc biệt | Khi WP_Query đủ dùng và an toàn hơn |
Tối ưu meta_query và tax_query
Đây là yếu tố ảnh hưởng lớn nhất đến tốc độ WP_Query. Một số tối ưu bạn nên áp dụng:
- Tránh meta_query dạng LIKE vì gây full table scan.
- Thêm index cho meta_key nếu lọc thường xuyên.
- Giảm số lượng meta_query lồng nhau.
- Với tax_query, tránh query quá nhiều term cùng lúc.
Sử dụng cache để tăng tốc Query
Những query nặng hoặc lặp lại nhiều lần nên được cache để giảm tải database.
<?php
global $wpdb;
$cache_key = 'home_latest_posts_sql';
$data = wp_cache_get( $cache_key );
if ( false === $data ) {
// Query trực tiếp bằng SQL, tối ưu hơn get_posts khi chỉ cần dữ liệu cơ bản
$sql = "
SELECT ID, post_title
FROM {$wpdb->posts}
WHERE post_type = 'post'
AND post_status = 'publish'
ORDER BY post_date DESC
LIMIT 10
";
$rows = $wpdb->get_results( $sql );
// Chuẩn hóa dữ liệu để dễ dùng ở template
$data = array_map( function( $row ) {
return [
'id' => (int) $row->ID,
'title' => $row->post_title,
'url' => get_permalink( $row->ID ),
];
}, $rows );
wp_cache_set( $cache_key, $data, '', 300 ); // cache 5 phút
}
foreach ( $data as $post ) {
echo '<p><a href="' . esc_url( $post['url'] ) . '">'
. esc_html( $post['title'] ) . '</a></p>';
}
?>
Cache đúng cách có thể giảm 50% – 80% số lượng query SQL.
Những sai lầm phổ biến khiến WordPress Query chậm
- Dùng
posts_per_page = -1ở site có dữ liệu lớn. - Meta_query phức tạp hoặc dùng LIKE.
- Không bật
no_found_rowskhi không phân trang. - Dùng WP_Query trong loop mà không reset.
- Dùng $wpdb trực tiếp nhưng không cache.
Chọn phương pháp nào? – Hướng dẫn nhanh
- Dùng WP_Query khi cần phân trang hoặc điều kiện lọc phức tạp.
- Dùng get_posts khi cần danh sách nhỏ và nhẹ.
- Dùng $wpdb khi cần SQL nâng cao hoặc hiệu năng cao.
- Dùng cache cho những truy vấn nặng hoặc lặp lại.
Kết luận
Không có phương pháp truy vấn nào phù hợp cho mọi tình huống. WP_Query mạnh nhưng nặng, get_posts nhanh và gọn, còn $wpdb cho bạn hiệu năng tối đa nhưng yêu cầu hiểu rõ database.
Hãy chọn đúng công cụ theo yêu cầu và tối ưu thêm bằng cache, no_found_rows, fields = ‘ids’, và hạn chế meta_query phức tạp. Đây là cách đơn giản nhưng hiệu quả để tăng tốc toàn bộ hệ thống WordPress.
Bình luận