DungNQ

1001 cách để trở thành Webmaster

Truy cập nhanh

  • Giới thiệu
  • Dịch vụ cài đặt WordPress miễn phí
  • Liên hệ

Powered by Genesis

You are here: Home

Hiệu chỉnh Google XML Sitemap với trang Sitemap Index

May 13, 2017 by robot Leave a Comment

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.

Filed Under: Plugins, Wordpress Tagged With: CatSQL GROUP BY YEAR, CatSQL ORDER BY, COUNT, DESC, eFromFormat, FROM, Google XML Sitemap, GROUP, Group By, Mega Wordpress, MONTH, ORDER, ORDER BY, p.ID, p.post_date_gmt, p.post_modified_gmt, Plugin Google XML Sitemap, Search Engine, SELECT, SELECT YEAR, Sitemap Index, Sitemap Index Ti, Sitemap Index Tiếp, WHERE, xCatSQL GROUP BY YEAR, xCatSQL ORDER BY, YEAR, YEAR and MONTH

Hiệu chỉnh Google XML Sitemap Plugin cho website có số lượng bài viết lớn

September 12, 2016 by dungnq Leave a Comment

Google XML Sitemap là một trong những plugin không thể thiếu của tôi, trước đây khi plugin này chưa hỗ trợ Multisite, tôi đã không sử dụng nó, nhưng rồi tới khi nó hỗ trợ, tôi lại không sử dụng tính năng cho Multisite của nó :D, đúng là ngịch lý của cuộc sống.

Về cơ bản, chức năng của nó không thay đổi nhiều, có một cải tiến lớn đó là việc hỗ trợ Nginx, với cấu hình sau, đây là những gì bạn cần cấu hình thêm khi chạy WordPress cùng Nginx

rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/index.php?xml_sitemap=params=$2" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;

Việc cấu hình trên, mục đích để  Rewrite đường dẫn sao cho thật dễ nhớ, không có thì cũng không sao cả, bạn sẽ có một link sitemap với vô số các tham biến ở sau. Tôi sử dụng cho việc không phải nhớ mỗi khi submit website lên Google Webmaster Tool, hay Bing.

Quay về nội dung chính, một plugin tốt như vậy, có hơn 1 triệu lượt download tại sao lại có vấn đề. Trở ngại nằm ở chỗ, khi xây dựng plugin, tác giả chưa tính tới việc dữ liệu sẽ dày lên trong tương lai, vốn là người mong muốn trải nghiệm với hệ thống lớn, tôi luôn sẵn sàng để kiểm tra đâu là plugin tốt, và đối với tôi, đó phải là plugin thiết kế tốt cho tương lai của dữ liệu khổng lồ.

Hai điểm quan trọng Plugin này mắc phải đó là sử dụng truy vấn SQL không tuân thủ nguyên tắc đơn giản.

//Statement to query the actual posts for this post type
      $qs = "
        SELECT
          p.ID,
          p.post_author,
          p.post_status,
          p.post_name,
          p.post_parent,
          p.post_type,
          p.post_date,
          p.post_date_gmt,
          p.post_modified,
          p.post_modified_gmt,
          p.comment_count
        FROM
          {$wpdb->posts} p
        WHERE
          p.post_password = ''
          AND p.post_type = '%s'
          AND p.post_status = 'publish'
          AND YEAR(p.post_date_gmt) = %d
          AND MONTH(p.post_date_gmt) = %d
          {$exPostSQL}
          {$exCatSQL}
        ORDER BY
          p.post_date_gmt DESC
      ";

Bạn thấy đấy, trong truy vấn WHERE tác giả sử dụng hàm YEAR và MONTH để so sánh, mục đích truy vấn này để lọc ra các bài viết có trong cùng một tháng. Tất nhiên bạn có thể thay đổi như sau để có thể giúp hệ thống chạy nhanh hơn, đừng quên comment lại các dòng trên nhé.

// @dungnq optimize start
                        if ($month == 12) {
                            $next_year = $year+1;
                            $next_month = '01';
                        }
                        else {
                            $next_year = $year;
                            $next_month = $month+1;
                        }
                        
                        $qs = "
        SELECT
          p.ID,
          p.post_author,
          p.post_status,
          p.post_name,
          p.post_parent,
          p.post_type,
          p.post_date,
          p.post_date_gmt,
          p.post_modified,
          p.post_modified_gmt,
          p.comment_count
        FROM
          {$wpdb->posts} p
        WHERE
          p.post_password = ''
          AND p.post_type = '%s'
          AND p.post_status = 'publish'
          AND p.post_date_gmt >= '{$year}-{$month}-01 00:00:00'
                                        AND p.post_date_gmt 
Thay đổi ở trên của tôi rất đơn giản, hay vi sử dụng hàm trong câu lệnh điều kiện WHERE tôi xác định luôn một khoảng thời gian nhất định từ là ngày phát hành bài viết phải từ 0 giờ này 1 của tháng, tới trước 0 giờ ngày 1 của tháng kế tiếp, những dòng trên đầu của tôi sử dụng để lấy ra tháng hiện tại và tháng kế tiếp, đặc biệt với tháng 12 thì cần nhảy lên 1 năm.

Còn một điểm lưu ý nữa, nhưng trong tôi nghĩ sẽ chia sẻ cùng các bạn trong tuần tới, nhừng quên ghé tham blog của tôi hàng tuần để nhận được những thông tin  về cách tối ưu WordPress với lượng dữ liệu khổng lồ nhé.

 

Filed Under: Plugins, Wordpress Tagged With: AND MONTH, AND YEAR, DESC, FROM, Google Webmaster Tool, Google XML Sitemap, Google XML Sitemap Plugin, Mega Wordpress, MONTH, ORDER, ORDER BY, p.post_date_gmt, SELECT, WHERE, YEAR

Điều chỉnh WordPress Ping

September 5, 2016 by dungnq Leave a Comment

Nếu bạn là một blogger sử dụng WordPress như một công cụ đề xuất bản những bài viết của mình, thì nội dung này sẽ không hề hợp với bạn. Ở đây tôi đóng vai trò là một người quản trị, sử dụng wordpress cho những hệ thống lớn, có nhiều người truy cập, cũng như số lượng bài viết mỗi ngày được phát hành là không hề nhỏ?

Vấn đề là gì, như những gì bạn có thể đã biết, WordPress cho  một cơ chế ping tới các search engine, nghĩa là sau khi bạn phát hành bài viết, bằng cách này hay cách khác, WordPress sẽ tự động đẩy những nội dung tới các cỗ máy tìm kiếm để thông báo bài viết của bạn tồn tại, hoặc đã được chỉnh sửa.

Thảm họa xảy ra là gì? Nếu 1 ngày bạn chỉ có từ 1 – 2 bài viết, thì không nói, nhưng với một hệ thống lớn, số lượng có thể lên đến 100, 200, thậm chí là 1000 bài viết cần xuất bản mỗi ngày. Tới đây chính là giới hạn của WordPress, hãy thử tưởng tượng, trong một lần xử lý, hệ thống sẽ ping tới Search Engine từ 100 đến 1000 lần, tất nhiên còn phụ thuộc vào tốc độ kết nối, khả năng xử lý của CPU… nhưng cái mà tôi đề cập tới chính là tài nguyên bị giữ lại cho việc xử lý này mới thực là vấn đề, PHP không phải là ngôn ngũ viết tối ưu cho bộ nhớ trong RAM, nên chạy càng lâu, vòng lặp càng lớn thì hệ thống bạn sớm bị cạn kiệt. Hệ quả là, server còi của bạn không còn đủ tài nguyên để phục vụ khách hàng truy cập nữa.

Điều bạn nên làm là gì, hay tìm  đoan code sau trong thư mục wp-include/comment.php, tìm kiếm hàm do_all_pings và thay đổi theo mẫu dưới đây của tôi gợi ý.

/**
 * Perform all pingbacks, enclosures, trackbacks, and send to pingback services.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 */
function do_all_pings() {
  global $wpdb;
  
    $limit = get_option('posts_per_page', 10); // @dungnq get limit of post per page
  // Do pingbacks
  $count=0; // @dungnq count
  while ($ping = $wpdb->get_row("SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_pingme' LIMIT 1")) {
    delete_metadata_by_mid( 'post', $ping->meta_id );
    pingback( $ping->post_content, $ping->ID );
    $count++; //@dungnq
    if ($count >= $limit) break; // @dungnq
  }

  // Do Enclosures
  $count=0; // @dungnq count
  while ($enclosure = $wpdb->get_row("SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_encloseme' LIMIT 1")) {
    delete_metadata_by_mid( 'post', $enclosure->meta_id );
    do_enclose( $enclosure->post_content, $enclosure->ID );
    $count++; //@dungnq
    if ($count >= $limit) break; // @dungnq
  }

  // Do Trackbacks
  //$trackbacks = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE to_ping  '' AND post_status = 'publish'");
  $trackbacks = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE to_ping  '' AND post_status = 'publish' LIMIT $limit");
  if ( is_array($trackbacks) )
    foreach ( $trackbacks as $trackback )
      do_trackbacks($trackback);

  //Do Update Services/Generic Pings
  generic_ping();
}

Thay vì sử dụng vòng lặp vô tận cho tới khi hết các post mới nhất cần ping, tôi chỉnh lại một chút thôi, lấy số giới hạn là số lượng post hiển thị trên trang chủ hoặc feed, sau đó sử dụng bộ đếm để thoát khỏi vòng lặp while.

Tôi đã hoàn toàn giữ lại code của WordPress để bạn tham khảo? Nếu bạn vẫn có suy nghĩ là WordPress chỉ là nền tảng của các blogger, hay tham khảo tờ The Sun nổi tiếng của UK, các kỹ sư đã biết wordpress trở thành một nền tảng cho báo chí vô cùng linh hoạt. Còn sức mạnh của nó đến đâu, tùy bạn kiểm chứng, tôi chỉ có thể chia sẻ rằng, nó nằm trong chính khối óc của bạn, hãy tận dụng thành quả 10+ năm tuyệt vời của những con người xây dựng nên WordPress, đừng biến mình trở thành những nhà khoa học đi phát minh lại những bánh xe.

Filed Under: Wordpress Tagged With: 'post', 'posts_per_page', bài viết, Do Enclosures, Do Trackbacks, Do Update Services, dPress Ping, FROM, Generic Pings, LIMIT, Mega Wordpress, Search Engine, SELECT, SELECT ID, SELECT ID FROM, The Sun, WHERE, Wordpress Core, WordPress Ping, WordPress Ping Nếu

  • 1
  • 2
  • 3
  • …
  • 5
  • Next Page »

Tìm kiếm

Mây thẻ

All in One SEO CAPTCHA Code CatSQL ORDER BY code COUNT CPU Trong DESC eFromFormat FROM Google XML Sitemap GROUP Group By HostGator Jira Store LIBRARY LIMIT Mega Wordpress miễn phí MONTH NamNH13 NET Nuke Nginx Proxy Open Graph Tags ORDER ORDER BY p.ID p.post_date_gmt p.post_modified_gmt PATH Route 53 Search Engine SELECT SEO On Oage SEO On Page Server DMO Server Lunix Server Production Việt Nam WHERE Wordpress Wordpress Multisite WP Supper Cache xCatSQL ORDER BY YEAR YEAR and MONTH

Đăng ký bản tin

Đừng bỏ lỡ những chỉa sẻ hàng ngày của tôi về Wordpress, Nginx, jQuery, PHP...

Bài viết mới nhất

  • Hiệu chỉnh Google XML Sitemap với trang Sitemap Index May 13, 2017
  • Hiệu chỉnh Google XML Sitemap Plugin cho website có số lượng bài viết lớn September 12, 2016
  • Điều chỉnh WordPress Ping September 5, 2016
  • Google XML Sitemap September 1, 2016
  • Không nên sử dụng hàm get_page_by_title August 31, 2016