Làm cách nào để mở rộng WP_Query để bao gồm bảng tùy chỉnh trong truy vấn?


31

Tôi đã được nhiều ngày về vấn đề này bây giờ. Ban đầu, đó là cách lưu trữ dữ liệu người theo dõi của người dùng trong cơ sở dữ liệu, mà tôi đã nhận được một số đề xuất hay ở đây tại WordPress Hỏi. Sau khi làm theo các khuyến nghị tôi đã thêm một bảng mới như thế này:

id  leader_id   follower_id
1   2           4
2   3           10
3   2           10

Trong bảng trên, hàng đầu tiên có người dùng có ID là 2 người đang được theo dõi bởi người dùng có ID là 4. Ở hàng thứ hai, người dùng có ID 3 đang được theo dõi bởi người dùng có ID của 10. Logic tương tự áp dụng cho hàng thứ ba.

Bây giờ, về cơ bản, tôi muốn mở rộng WP_Query để tôi có thể giới hạn các bài đăng được tìm nạp đến, chỉ bởi (các) nhà lãnh đạo của người dùng. Vì vậy, cân nhắc bảng trên, nếu tôi chuyển ID người dùng 10 cho WP_Query, kết quả chỉ nên chứa các bài đăng của ID người dùng 2 và ID người dùng 3.

Tôi đã tìm kiếm rất nhiều cố gắng để tìm một câu trả lời. Ngoài ra, tôi đã thấy bất kỳ hướng dẫn nào để giúp tôi hiểu cách mở rộng lớp WP_Query. Tôi đã thấy câu trả lời của Mike Schinkel (mở rộng WP_Query) cho các câu hỏi tương tự, nhưng tôi thực sự không hiểu làm thế nào để áp dụng nó vào nhu cầu của mình. Sẽ thật tuyệt nếu ai đó có thể giúp tôi với điều này.

Liên kết đến câu trả lời của Mike theo yêu cầu: Liên kết 1 , Liên kết 2


Vui lòng thêm một liên kết đến câu trả lời của Mikes.
kaiser

1
bạn có thể đưa ra một ví dụ về những gì bạn sẽ truy vấn? WP_Querylà để nhận bài viết và tôi không hiểu làm thế nào điều này liên quan đến bài viết.
mor7ifer

@kaiser Tôi đã cập nhật câu hỏi với các liên kết đến câu trả lời của Mike.
Giăng

@ m0r7if3r »Tôi muốn mở rộng WP_Query để tôi có thể giới hạn các bài đăng được tìm nạp đến, chỉ bởi (các) nhà lãnh đạo của người dùng«, tương tự như "lấy bài đăng của tác giả".
kaiser

2
@ m0r7if3r Bài viết chính xác là những gì tôi cần truy vấn. Nhưng các bài đăng được tìm nạp phải là bởi người dùng được liệt kê là người lãnh đạo của một người dùng nhất định trong bảng tùy chỉnh. Vì vậy, nói cách khác, tôi muốn nói với WP_Query, hãy tìm nạp tất cả các bài đăng của tất cả người dùng được liệt kê là người lãnh đạo của người dùng có ID '10' trong bảng tùy chỉnh.
John

Câu trả lời:


13

Từ chối trách nhiệm quan trọng: cách thích hợp để làm điều này KHÔNG phải là sửa đổi cấu trúc bảng của bạn, mà là sử dụng wp_usermeta. Sau đó, bạn sẽ không cần tạo bất kỳ SQL tùy chỉnh nào để truy vấn các bài đăng của mình (mặc dù bạn vẫn sẽ cần một số SQL tùy chỉnh để nhận danh sách mọi người báo cáo cho người giám sát cụ thể - ví dụ như trong phần Quản trị viên). Tuy nhiên, vì OP đã hỏi về việc viết SQL tùy chỉnh, đây là cách thực hành tốt nhất hiện nay để đưa SQL tùy chỉnh vào Truy vấn WordPress hiện có.

Nếu bạn đang thực hiện các phép nối phức tạp, bạn không thể chỉ sử dụng bộ lọc post_where, vì bạn sẽ cần sửa đổi phép nối, chọn và có thể nhóm theo hoặc sắp xếp theo các phần của truy vấn.

Đặt cược tốt nhất của bạn là sử dụng bộ lọc 'post_clauses'. Đây là một bộ lọc rất hữu ích (không nên lạm dụng!) Cho phép bạn chắp thêm / sửa đổi các phần khác nhau của SQL được tạo tự động bởi nhiều dòng mã trong lõi WordPress. Chữ ký gọi lại bộ lọc là: function posts_clauses_filter_cb( $clauses, $query_object ){ }và nó mong bạn quay trở lại $clauses.

Các khoản

$clauseslà một mảng chứa các khóa sau; mỗi khóa là một chuỗi SQL sẽ được sử dụng trực tiếp trong câu lệnh SQL cuối cùng được gửi đến cơ sở dữ liệu:

  • Ở đâu
  • nhóm
  • tham gia
  • đặt bởi
  • khác biệt
  • lĩnh vực
  • giới hạn

Nếu bạn đang thêm một bảng vào cơ sở dữ liệu (chỉ làm điều này nếu bạn hoàn toàn không thể tận dụng post_meta, user_meta hoặc phân loại), có lẽ bạn sẽ cần phải chạm vào nhiều hơn một trong các mệnh đề này, ví dụ: fields"CHỌN" một phần của câu lệnh SQL), join(tất cả các bảng của bạn, không phải là bảng trong mệnh đề "TỪ" của bạn) và có thể là orderby.

Sửa đổi các khoản

Cách tốt nhất để làm điều này là thay thế khóa có liên quan từ $clausesmảng bạn nhận được từ bộ lọc:

$join = &$clauses['join'];

Bây giờ, nếu bạn sửa đổi $join, bạn sẽ thực sự sửa đổi trực tiếp $clauses['join']để thay đổi sẽ có $clauseskhi bạn trả lại.

Giữ nguyên các khoản gốc

Rất có thể (không, nghiêm túc, lắng nghe) bạn sẽ muốn duy trì SQL hiện có mà WordPress tạo ra cho bạn. Nếu không, có lẽ bạn nên xem posts_requestbộ lọc thay vào đó - đó là truy vấn myQuery hoàn chỉnh ngay trước khi nó được gửi đến cơ sở dữ liệu, do đó bạn hoàn toàn có thể tự mình ghi lại nó. Tại sao bạn muốn làm điều này? Bạn có thể không.

Vì vậy, để bảo toàn SQL hiện có trong các mệnh đề, hãy nhớ nối thêm các mệnh đề, không gán cho chúng (ví dụ: $join .= ' {NEW SQL STUFF}';không sử dụng $join = '{CLOBBER SQL STUFF}';. Lưu ý rằng vì mỗi phần tử của $clausesmảng là một chuỗi, nếu bạn muốn nối vào nó, bạn có thể muốn chèn một khoảng trắng trước bất kỳ mã thông báo ký tự nào khác, nếu không bạn có thể sẽ tạo ra một số lỗi cú pháp SQL.

Bạn chỉ có thể giả sử sẽ luôn có một cái gì đó trong mỗi mệnh đề, và vì vậy hãy nhớ bắt đầu mỗi chuỗi mới bằng một khoảng trắng, như trong : $join .= ' my_table, hoặc, bạn luôn có thể thêm một dòng nhỏ chỉ thêm một khoảng trắng nếu bạn cần:

$join = &$clauses['join'];
if (! empty( $join ) ) $join .= ' ';
$join .= "JOIN my_table... "; // <-- note the space at the end
$join .= "JOIN my_other_table... ";


return $clauses;

Đó là một điều phong cách hơn bất cứ điều gì khác. Điều quan trọng cần nhớ là: luôn để lại một khoảng trắng TRƯỚC chuỗi của bạn nếu bạn đang nối thêm một mệnh đề đã có một số SQL trong đó!

Đặt nó lại với nhau

Nguyên tắc đầu tiên của phát triển WordPress là cố gắng sử dụng càng nhiều chức năng cốt lõi càng tốt. Đây là cách tốt nhất để chứng minh công việc của bạn trong tương lai. Giả sử nhóm nòng cốt quyết định rằng WordPress sẽ sử dụng SQLite hoặc Oracle hoặc một số ngôn ngữ cơ sở dữ liệu khác. Bất kỳ myQuery viết tay nào cũng có thể trở nên không hợp lệ và phá vỡ plugin hoặc chủ đề của bạn! Tốt hơn là để WP tự tạo càng nhiều SQL càng tốt và chỉ cần thêm các bit bạn cần.

Vì vậy, đơn hàng đầu tiên của doanh nghiệp đang tận dụng WP_Queryđể tạo ra càng nhiều truy vấn cơ sở của bạn càng tốt. Phương pháp chính xác mà chúng tôi sử dụng để làm điều này phụ thuộc phần lớn vào nơi danh sách các bài đăng này được cho là xuất hiện. Nếu đó là một phần phụ của trang (không phải truy vấn chính của bạn), bạn sẽ sử dụng get_posts(); Nếu đó là truy vấn chính, tôi cho rằng bạn có thể sử dụng query_posts()và thực hiện với nó, nhưng cách thích hợp để thực hiện là chặn truy vấn chính trước khi truy cập vào cơ sở dữ liệu (và sử dụng chu kỳ máy chủ), vì vậy hãy sử dụng requestbộ lọc.

Được rồi, vì vậy bạn đã tạo truy vấn của mình và SQL sắp được tạo. Vâng, trên thực tế, nó đã được tạo, chỉ không được gửi đến cơ sở dữ liệu. Bằng cách sử dụng posts_clausesbộ lọc, bạn sẽ thêm bảng mối quan hệ nhân viên của mình vào hỗn hợp. Hãy gọi bảng này {$ wpdb-> tiền tố}. 'user_relationship' và đó là một bảng giao nhau. . .. nhưng tôi lạc đề).

Nếu tôi hiểu những gì bạn muốn làm, bạn muốn thông qua ID của Người dẫn đầu và sau đó chỉ xem các bài đăng của Người theo dõi đó. Tôi hy vọng tôi đã làm đúng. Nếu nó không đúng, bạn sẽ phải lấy những gì tôi nói và điều chỉnh nó theo nhu cầu của bạn. Tôi sẽ gắn bó với cấu trúc bảng của bạn: chúng tôi có một leader_idvà a follower_id. Vì vậy, THAM GIA sẽ được bật {$wpdb->posts}.post_authordưới dạng khóa ngoại đối với 'follower_id' trên bảng 'user_relationship' của bạn.

add_filter( 'posts_clauses', 'filter_by_leader_id', 10, 2 ); // we need the 2 because we want to get all the arguments

function filter_by_leader_id( $clauses, $query_object ){
  // I don't know how you intend to pass the leader_id, so let's just assume it's a global
  global $leader_id;

  // In this example I only want to affect a query on the home page.
  // This is where the $query_object is used, to help us avoid affecting
  // ALL queries (since ALL queries pass through this filter)
  if ( $query_object->is_home() ){
    // Now, let's add your table into the SQL
    $join = &$clauses['join'];
    if (! empty( $join ) ) $join .= ' '; // add a space only if we have to (for bonus marks!)
    $join .= "JOIN {$wpdb->prefix}employee_relationship EMP_R ON EMP_R.follower_id = {$wpdb->posts}.author_id";

    // And make sure we add it to our selection criteria
    $where = &$clauses['where'];
    // Regardless, you always start with AND, because there's always a '1=1' statement as the first statement of the WHERE clause that's added in by WP/
    // Just don't forget the leading space!
    $where .= " AND EMP_R.leader_id={$leader_id}"; // assuming $leader_id is always (int)

    // And I assume you'll want the posts "grouped" by user id, so let's modify the groupby clause
    $groupby = &$clauses['groupby'];
    // We need to prepend, so...
    if (! empty( $groupby ) ) $groupby = ' ' . $groupby; // For the show-offs
    $groupby = "{$wpdb->posts}.post_author" . $groupby;
  }

  // Regardless, we need to return our clauses...
  return $clauses;
}

13

Tôi đang trả lời câu hỏi này rất muộn và lời xin lỗi của tôi cũng vậy. Tôi đã quá bận rộn với thời hạn để tham gia vào việc này.

Rất cảm ơn @ m0r7if3r và @kaiser trong việc cung cấp các giải pháp cơ bản mà tôi có thể mở rộng và triển khai trong ứng dụng của mình. Câu trả lời này cung cấp chi tiết về sự thích ứng của tôi đối với các giải pháp được cung cấp bởi @ m0r7if3r và @kaiser.

Đầu tiên, hãy để tôi giải thích tại sao câu hỏi này được hỏi ngay từ đầu. Từ câu hỏi và các nhận xét mà người ta có thể thu thập được rằng tôi đang cố gắng để WP_Query thu hút các bài đăng của tất cả người dùng (người lãnh đạo) mà một người dùng (người theo dõi) nhất định theo dõi. Mối quan hệ giữa người theo dõi và người lãnh đạo được lưu trữ trong một bảng tùy chỉnh follow. Giải pháp phổ biến nhất cho vấn đề này là lấy ID người dùng của tất cả các nhà lãnh đạo của người theo dõi từ bảng theo dõi và đặt nó vào một mảng. Xem bên dưới:

global $wpdb;
$results = $wpdb->get_results($wpdb->prepare('SELECT leader_id FROM cs_follow WHERE follower_id = %s', $user_id));

foreach($results as $result)
    $leaders[] = $result->leader_id;

Khi bạn có mảng các nhà lãnh đạo, bạn có thể chuyển nó làm đối số cho WP_Query. Xem bên dưới:

if (isset($leaders)) $authors = implode(',', $leaders); // Necessary as authors argument of WP_Query only accepts string containing post author ID's seperated by commas

$args = array(
    'post_type'         => 'post',
    'posts_per_page'    => 10,
    'author'            => $authors
);

$wp_query = new WP_Query( $args );

// Normal WordPress loop continues

Giải pháp trên là cách đơn giản nhất để đạt được kết quả mong muốn của tôi. Tuy nhiên, nó là không thể mở rộng. Khoảnh khắc bạn có một người theo dõi sau hàng chục và hàng ngàn nhà lãnh đạo, mảng kết quả của ID nhà lãnh đạo sẽ trở nên cực kỳ lớn và buộc trang web WordPress của bạn phải sử dụng 100 MB - 250 MB bộ nhớ cho mỗi lần tải trang và cuối cùng làm sập trang web. Giải pháp cho vấn đề này là chạy truy vấn SQL trực tiếp trên cơ sở dữ liệu và tìm nạp các bài đăng có liên quan. Đó là khi giải pháp của @ m0r7if3r được giải cứu. Theo khuyến nghị của @ kaiser, tôi bắt đầu thử nghiệm cả hai triển khai. Tôi đã nhập khoảng 47K người dùng từ tệp CSV để đăng ký chúng trên bản cài đặt thử nghiệm mới của WordPress. Bản cài đặt đang chạy chủ đề Twenty Eleven. Sau đó, tôi chạy một vòng lặp for để làm cho khoảng 50 người dùng theo dõi mọi người dùng khác. Sự khác biệt về thời gian truy vấn cho cả giải pháp của @kaiser và @ m0r7if3r là đáng kinh ngạc. Giải pháp @ kaiser thường mất khoảng 2 đến 5 giây cho mỗi truy vấn. Biến thể tôi cho là xảy ra khi WordPress lưu trữ các truy vấn để sử dụng sau này. Mặt khác, giải pháp của @ m0r7if3r đã thể hiện thời gian truy vấn trung bình 0,02 ms. Để thử nghiệm cả hai giải pháp, tôi đã lập chỉ mục BẬT cho cột Leader_id. Không có chỉ mục, đã có sự gia tăng đáng kể thời gian truy vấn.

Việc sử dụng bộ nhớ khi sử dụng giải pháp dựa trên mảng là khoảng 100-150 MB và giảm xuống còn 20 MB khi chạy SQL trực tiếp.

Tôi đã gặp khó khăn với giải pháp của @ m0r7if3r khi tôi cần chuyển ID người theo dõi đến chức năng lọc của post_where. Theo kinh nghiệm của tôi, WordPress cho phép không có phương tiện chuyển một biến nào cho các hàm filer. Bạn có thể sử dụng các biến toàn cầu, nhưng tôi muốn tránh toàn cầu. Tôi đã kết thúc việc mở rộng WP_Query để cuối cùng giải quyết vấn đề. Vì vậy, đây là giải pháp cuối cùng tôi thực hiện (dựa trên giải pháp của @ m0r7if3r).

class WP_Query_Posts_by_Leader extends WP_Query {
    var $follower_id;

    function __construct($args=array()) {
        if(!empty($args['follower_id'])) {
            $this->follower_id = $args['follower_id'];
            add_filter('posts_where', array($this, 'posts_where'));
        }

        parent::query($args);
    }

    function posts_where($where) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'follow';
        $where .= $wpdb->prepare(" AND post_author IN (SELECT leader_id FROM " . $table_name . " WHERE follower_id = %d )", $this->follower_id);
        return $where;
    }
}


$args = array(
    'post_type'         => 'post',
    'posts_per_page'    => 10,
    'follower_id'       => $follower_id
);

$wp_query = new WP_Query_Posts_by_Leader( $args );

Lưu ý: Cuối cùng tôi đã thử giải pháp trên với 1,2 triệu mục trong bảng theo dõi. Thời gian truy vấn trung bình là khoảng 0,060 ms.


3
Tôi chưa bao giờ nói với bạn rằng tôi đánh giá cao cuộc thảo luận về câu hỏi này. Bây giờ tôi phát hiện ra rằng tôi đã bỏ lỡ nó, tôi đã thêm một upvote :)
kaiser

8

Bạn có thể làm điều này với một giải pháp SQL hoàn toàn bằng posts_wherebộ lọc. Đây là một ví dụ về điều đó:

if( some condition ) 
    add_filter( 'posts_where', 'wpse50305_leader_where' );
    // lol, question id is the same forward and backward

function wpse50305_leader_where( $where ) {
    $where .= $GLOBALS['wpdb']->prepare( ' AND post_author '.
        'IN ( '.
            'SELECT leader_id '.
            'FROM custom_table_name '.
            'WHERE follower_id = %s'.
        ' ) ', $follower_id );
    return $where;
}

Tôi nghĩ có thể có một cách để làm điều này JOINlà tốt, nhưng tôi không thể đưa ra nó. Tôi sẽ tiếp tục chơi với nó và cập nhật câu trả lời nếu tôi nhận được nó.

Cách khác, như @kaiser đề xuất, bạn có thể chia thành hai phần: nhận các nhà lãnh đạo và thực hiện truy vấn. Tôi có cảm giác điều này có thể kém hiệu quả hơn, nhưng chắc chắn đó là cách dễ hiểu hơn. Bạn sẽ phải tự kiểm tra hiệu quả để xác định phương pháp nào tốt hơn, vì các truy vấn SQL lồng nhau có thể trở nên khá chậm.

TỪ Ý KIẾN:

Bạn nên đặt hàm trong của bạn functions.phpvà thực hiện add_filter()đúng trước khi query()phương thức WP_Queryđược gọi. Ngay lập tức theo đó, bạn sẽ remove_filter()không ảnh hưởng đến các truy vấn khác.


1
Chỉnh sửa A của bạn và thêm prepare(). Hy vọng bạn không tâm trí chỉnh sửa. Và vâng: Hiệu suất được đo bằng OP. Dù sao: Tôi vẫn nghĩ rằng điều này chỉ đơn giản là usermeta và không có gì khác.
kaiser

@ m0r7if3r Thx vì đã thử một giải pháp. Tôi vừa đăng một bình luận để trả lời câu trả lời của kaiser, với những lo ngại về các vấn đề có thể mở rộng. Xin vui lòng đưa nó vào xem xét.
John

1
@kaiser Đừng bận tâm, thực tế thì tôi đánh giá cao điều đó :)
mor7ifer

@ m0r7if3r Cảm ơn. Có những người như bạn trong cộng đồng đá :)
kaiser

1
Bạn nên đặt hàm trong của bạn functions.phpvà thực hiện add_filter()đúng trước khi query()phương thức WP_Queryđược gọi. Ngay lập tức theo đó, bạn sẽ remove_filter()không ảnh hưởng đến các truy vấn khác. Tôi không chắc vấn đề với việc viết lại URL sẽ là gì, tôi đã sử dụng posts_wherenhiều lần và chưa bao giờ thấy điều đó ...
mor7ifer

6

Thẻ mẫu

Chỉ cần đặt cả hai chức năng trong functions.phptập tin của bạn . Sau đó điều chỉnh chức năng 1 và thêm tên bảng tùy chỉnh của bạn. Sau đó, bạn cần một số thử / lỗi để thoát khỏi ID người dùng hiện tại bên trong mảng kết quả (xem bình luận).

/**
 * Get "Leaders" of the current user
 * @param int $user_id The current users ID
 * @return array $query The leaders
 */
function wpse50305_get_leaders( $user_id )
{
    global $wpdb;

    return $wpdb->query( $wpdb->prepare(
        "
            SELECT `leader_id`, `follower_id`
            FROM %s
                WHERE `follower_id` = %s
            ORDERBY `leader_id` ASC
        ",
        // Edit the table name
        "{$wpdb->prefix}custom_table_name"
        $user_id
    ) );
}

/**
 * Get posts array that contain posts by 
 * "Leaders" the current user is following
 * @return array $posts Posts that are by the current "Leader
 */
function wpse50305_list_posts_by_leader()
{
    get_currentuserinfo();
    global $current_user;

    $user_id = $current_user->ID;

    $leaders = wpse5035_get_leaders( $user_id );
    // could be that you need to loop over the $leaders
    // and get rid of the follower ids

    return get_posts( array(
        'author' => implode( ",", $leaders )
    ) );
}

Bên trong mẫu

Ở đây bạn có thể làm bất cứ điều gì bạn muốn với kết quả của bạn.

foreach ( wpse50305_list_posts_by_leader() as $post )
{
    // do something with $post
}

LƯU Ý Chúng tôi không có testdata, v.v. vì vậy, ở trên là một chút trò chơi đoán. Hãy chắc chắn rằng bạn chỉnh sửa câu trả lời này với những gì hiệu quả với bạn, để chúng tôi có kết quả hài lòng cho những người đọc sau này. Tôi sẽ phê duyệt chỉnh sửa trong trường hợp bạn có đại diện quá thấp. Sau đó bạn cũng có thể xóa ghi chú này. Cảm ơn.


2
JOINnhiều hơn nữa tốn kém. Thêm vào đó, như tôi đã đề cập, chúng tôi không có dữ liệu kiểm tra, vì vậy vui lòng kiểm tra cả câu trả lời và khai sáng cho chúng tôi với kết quả của bạn.
kaiser

1
WP_Query tự hoạt động với THAM GIA giữa bảng bài viết và postmeta khi truy vấn. Tôi đã thấy mức sử dụng bộ nhớ PHP tăng lên 70MB - 200MB cho mỗi lần tải trang. Chạy một cái gì đó như thế với nhiều người dùng đồng thời sẽ cần một cơ sở hạ tầng cực đoan. Tôi đoán là vì WordPress đã thực hiện kỹ thuật tương tự, THAM GIA nên đánh thuế ít hơn so với làm việc với mảng ID.
John

1
@ John tốt nghe. thực sự muốn biết sắp tới
kaiser

4
Ok đây là kết quả kiểm tra. Đối với điều này, tôi đã thêm khoảng 47K người dùng từ một tệp csv. Sau đó, chạy một vòng lặp for để khiến 45 người dùng đầu tiên theo dõi mọi người dùng khác. Điều này dẫn đến 3,704.951 hồ sơ được lưu vào bảng tùy chỉnh của tôi. Ban đầu, giải pháp của @ m0r7if3r cho tôi thời gian truy vấn là 95 giây, sau đó giảm xuống còn 0,020 ms sau khi bật chỉ mục ON trên cột Leader_id. Tổng bộ nhớ PHP tiêu thụ là khoảng 20 MB. Mặt khác, giải pháp của bạn mất khoảng 2 đến 5 giây để truy vấn với việc lập chỉ mục BẬT. Tổng bộ nhớ PHP tiêu thụ là khoảng 117 MB.
Giăng

1
Tôi thêm một câu trả lời khác (chúng ta có thể xử lý và sửa đổi / chỉnh sửa trên đó) vì định dạng mã trong các bình luận chỉ đơn giản là hút: P
kaiser

3

Lưu ý: Câu trả lời này ở đây là để tránh thảo luận mở rộng trong các bình luận

  1. Tại đây, hãy viết mã OP từ các bình luận, để thêm nhóm người dùng thử đầu tiên. Tôi phải được sửa đổi thành một ví dụ thực tế.

    for ( $j = 2; $j <= 52; $j++ ) 
    {
        for ( $i = ($j + 1); $i <= 47000; $i++ )
        {
            $rows_affected = $wpdb->insert( $table_name, array( 'leader_id' => $i, 'follower_id' => $j ) );
        }
    }
    

    OP About Test Đối với điều này, tôi đã thêm khoảng 47K người dùng từ tệp csv. Sau đó, chạy một vòng lặp for để khiến 45 người dùng đầu tiên theo dõi mọi người dùng khác.

    • Điều này dẫn đến 3,704.951 hồ sơ được lưu vào bảng tùy chỉnh của tôi.
    • Ban đầu, giải pháp của @ m0r7if3r cho tôi thời gian truy vấn là 95 giây, sau đó giảm xuống còn 0,020 ms sau khi bật chỉ mục ON trên cột Leader_id. Tổng bộ nhớ PHP tiêu thụ là khoảng 20 MB.
    • Mặt khác, giải pháp của bạn mất khoảng 2 đến 5 giây để truy vấn với việc lập chỉ mục BẬT. Tổng bộ nhớ PHP tiêu thụ là khoảng 117 MB.
  2. Câu trả lời của tôi cho bài kiểm tra này:

    một thử nghiệm "thực tế hơn": Cho phép mọi người dùng theo dõi $leader_amount = rand( 0, 5 );và sau đó thêm số lượng $leader_amount x $random_ids = rand( 0, 47000 );cho mỗi người dùng. Cho đến nay, điều chúng ta biết là: Giải pháp của tôi sẽ cực kỳ tồi tệ nếu người dùng theo dõi người dùng khác. Hơn nữa: Bạn có thể chỉ ra cách bạn thực hiện bài kiểm tra và chính xác nơi bạn đã thêm bộ tính giờ.

    Tôi cũng phải nói rằng việc theo dõi thời gian trên có thể thực sự được đo, vì nó cũng sẽ mất thời gian để tính toán vòng lặp với nhau. Tốt hơn là lặp qua bộ ID kết quả trong vòng lặp thứ hai.

tiếp tục xử lý ở đây


2
Lưu ý cho những người đã theo dõi Q này: Tôi đang trong quá trình đo hiệu suất trong các điều kiện khác nhau và sẽ đăng kết quả trong một ngày hoặc 3. Đây là nhiệm vụ cực kỳ tốn thời gian do quy mô của dữ liệu thử nghiệm cần phải có tạo ra.
Giăng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.