Tiếp tục chia sẻ các kinh nghiệm của bản thân với hệ thống dữ liệu lớn của WordPress cùng các plugin phổ biến. Google XML Sitemap là plugin không thể thiếu trong bất kỳ hệ thống nào, đây là plugin cung cấp cho webmaster công cụ tuyệt với để cho Google, Bing và các Search Engine khác biết sự tồn tại nội dung của bạn khi phát hành. Tuy nhiên, do giới hạn của việc thiết kế cho blog cỡ nhỏ, các plugin và bản thân WordPress cũng chưa tính hết được các vấn đề gặp phải khi hệ thống có những bài viết lớn dần lên.
Nếu bạn từng biết về SEO, thì sitemap là công cụ quan trọng để bạn cho các Search Engine biết được trong toàn bộ website của bạn có gì, từ đó các con robot, hay gọi là các “con bót” của bộ máy tìm kiếm sẽ căn cứ vào đó để đặt những bước chân đầu tiên khám phá nội dung trên website của bạn. Hôm nay tôi xin chi sẻ cùng các bạn vấn đề thứ 2 tôi gặp phải khi sử dụng Google XML Sitemap, đó là trong Sitemap Index. Vấn để tôi gặp phải là gì? Nếu lượng dữ liệu trên website của bạn đủ lớn, tức là nội dung phát hành trải rộng trong suốt 20 năm chẳng hạn, vậy con số chỉ mục theo từng tháng sẽ là 20 x 12 = 240 trang. Có vẻ không phải là nhiều, nhưng yêu cầu của Google đâu có đơn giản vậy, nó cần biết thời gian cập nhật gần nhất là khi nào? Cộng thêm một số tiêu chí của Plugin Google XML Sitemap, thì chúng ta phải chạy một câu lệnh như sau
$q = " SELECT YEAR(p.post_date_gmt) AS `year`, MONTH(p.post_date_gmt) AS `month`, COUNT(p.ID) AS `numposts`, MAX(p.post_modified_gmt) as `last_mod` FROM {$wpdb->posts} p WHERE p.post_password = '' AND p.post_type = '" . esc_sql($postType) . "' AND p.post_status = 'publish' $exPostSQL $exCatSQL GROUP BY YEAR(p.post_date_gmt), MONTH(p.post_date_gmt) ORDER BY p.post_date_gmt DESC";
Tất nhiên, nếu như bạn đã đọc bài giới thiệu trước của tôi trong cùng chủ đề, bạn có thể nhận thấy một lỗi tôi đã nói trước đây, sử dụng các hàm trong truy vấn, đây là một điều tối kỵ khi lập trình SQL, nhất là với dữ liệu khổng lồ, ở đây tác giả còn vô cùng hoành tráng, khi sử dụng trong lệnh Group BY… Woa, nếu dữ liệu của tôi là cả triệu bản ghi, chắc tôi phải tính toán lâu lắm, chưa kể có thể ảnh hưởng tới các câu truy vấn khác. Vậy tôi đã sửa lại như thế nào?
//@dungnq optimize start //$posts = $wpdb->get_results($q); /** * Find min and max post_date_gmt * Each month to get year, month, numposts, last_mod to add the object array result * Ignore group by YEAR and MONTH function */ $q = " SELECT p.post_date_gmt FROM {$wpdb->posts} p WHERE p.post_password = '' AND p.post_type = '" . esc_sql($postType) . "' AND p.post_status = 'publish' $exPostSQL $exCatSQL ORDER BY p.post_date_gmt DESC"; $max_time = $wpdb->get_var($q); $q = "SELECT p.post_date_gmt FROM {$wpdb->posts} p WHERE p.post_password = '' AND p.post_type = '" . esc_sql($postType) . "' AND p.post_status = 'publish' $exPostSQL $exCatSQL ORDER BY p.post_date_gmt ASC"; $min_time = $wpdb->get_var($q); $time_min = Datetime::createFromFormat('Y-m-d H:i:s', $min_time); $time_max = Datetime::createFromFormat('Y-m-d H:i:s', $max_time); $time = $time_max; #modify time min to fist time of the month $time_min = Datetime::createFromFormat('Y-m-d H:i:s', $time_min->format("Y-m-01 00:00:00")); $posts = array(); do { #var_dump($time); $month = $time->format('m'); $year = $time->format('Y'); if ($month == 12) { $next_year = $year+1; $next_month = '01'; } else { $next_year = $year; $next_month = $month+1; } $q = " SELECT YEAR(p.post_date_gmt) AS `year`, MONTH(p.post_date_gmt) AS `month`, COUNT(p.ID) AS `numposts`, MAX(p.post_modified_gmt) as `last_mod` FROM {$wpdb->posts} p WHERE p.post_password = '' AND p.post_type = '" . esc_sql($postType) . "' AND p.post_status = 'publish' AND p.post_date_gmt >= '{$year}-{$month}-01 00:00:00' AND p.post_date_gmt get_row($q); #var_dump($result); if ($post != null && $post->year > 0 && $post->month > 0) { array_push($posts, $post); } #previos month $time->modify("- 1 month"); }while ($time > $time_min); //@dungnq optimize end
Lý thuyết thì vô cùng đơn giản, với ý tưởng từ bài viết trước, thay vì sử dụng Group By để phân tách dữ liệu theo từng tháng, tôi tìm ngay ra 2 thời điểm, gần nhất và xa nhất, kế đó tôi chạy từng tháng kể từ thời điểm gần nhất, cho tới khi thời điểm xa nhất. Với mỗi vòng lặp, tôi lại tìm ra các thông tin mà hệ thống cần.
Bằng cách trên tôi đã đơn giản hóa một câu lệnh phức tạp, thành một chuỗi các lệnh đơn giản hơn, nhằm để xác định nhanh chóng một vấn đề tránh để các câu truy vấn chạy lâu quá và làm lock lại cả bảng dữ liệu.
Hy vọng với những cách trên, các bạn có thể tự tham khảo để sử dụng, cũng như hạn chế những lỗi gặp phải khi xây dựng hệ thống hay plugin cho cả triệu người dùng.
Leave a Comment