web-dev-qa-db-ja.com

大規模データベースに基づくランダムな著者の表示の効率

私は5人の著者のリストを表示しようとしています ランダムに 。これが私が見つけたいくつかの解決策です:

https://stackoverflow.com/questions/5502609/get-authors-randomlyhttps:// wordpress。 stackexchange.com/a/91326/1044

私はWP_User_Queryを次のように使用することを除いて、現在前者のソリューションを使用しています。

$args  = array(
    'role' => 'subscriber'
);
$wp_user_query = new WP_User_Query($args);
$authors = $wp_user_query->get_results();

// Shuffle list to get random results
shuffle($authors);

しかし、私の素人の理解では、この はユーザーの全リストを取得するでしょう 。ですから、 2000-5000ユーザー(またはそれ以上) 程度の人がいたのではないかと思っています。これは ページの読み込み に大きな影響を与えますか?どうすればこれをより効率的にすることができますか?

更新:

また、array_Rand()shuffle()よりも効率的な方法でしょうか。

2
Giraldi

効率を気にする場合は、 トランジェントAPI を使用してクエリを保存することをお勧めします。ランダム化したいものを格納するのは直感に反するように思えるかもしれませんが、クエリ全体を格納する場合は、結果の配列をいつでもランダム化して操作して必要な結果を得ることができます。

すべての購読者を取得して一時的に保存する方法は次のとおりです。最後にPHPをまっすぐに並べて結果をシャッフル/ランダム化し、 array_slice()を使用して最初の5つの結果を選びます

if ( false === ( $users = get_transient( 'get_all_subscribers' ) ) ) {
     // this code runs when there is no valid transient set

    $args  = array(
        'role'   => 'subscriber'
    );

    $wp_user_query = new WP_User_Query( $args );

    $users = $wp_user_query->get_results();

    set_transient( 'get_all_subscribers', $users );
}

// proceed with data normally
// randomize the stored result
shuffle( $users );
$Rand_users = array_slice( $users, 0, 5 );

var_dump( $Rand_users );

そしてトランジェントが最新であることを確認するために、ユーザーが更新または追加されたときにトランジェントを削除します。

// Create a simple function to delete our transient
function delete_all_subscribers_transient() {
     delete_transient( 'get_all_subscribers' );
}
// Add the function to the profile_update and user_registration hooks
add_action( 'profile_update', 'delete_all_subscribers_transient' );
add_action( 'user_register', 'delete_all_subscribers_transient' );
3
helgatheviking

5だけが必要な場合は、すべてのユーザーを取得したくはありません。

WP_User_Query()を使って5人のユーザをランダムに取得したい場合は、pre_user_queryフックを使ってorderby部分を上書きしてみてください。

$args  = array(
    'role'   => 'subscriber',
    'number' => 5,
);
add_action( 'pre_user_query', 'my_pre_user_query' );
$wp_user_query = new WP_User_Query( $args );

どこで

function my_pre_user_query( $q ){
    $q->query_orderby = ' ORDER BY Rand() ';

    // remove the hook
    remove_action( current_filter(), __FUNCTION__ );
}

更新:

この 記事 には、ORDER BY Rand()が始まる前に、特殊なWHERE条件を使用して行数を減らすためのコツが含まれています...それ。

あなたの場合のWHERE条件は、

WHERE Rand()<(SELECT ((5/COUNT(*))*10) FROM wp_users)

非常に多数のユーザーがいる場合は、この修正されたアクションコールバックを試すことができます。

function my_pre_user_query( $q ){
    $q->query_where = str_replace( 'WHERE 1=1', 'WHERE Rand()<(SELECT ((5/COUNT(*))*10) FROM wp_users) ', $q->query_where );
    $q->query_orderby = ' ORDER BY Rand() ';

    // remove hook
    remove_action( current_filter() , __FUNCTION__ );
}

上記の記事からのトリックがうまくいっているなら!

これは、修正されたコールバックのより一般的なバージョンです。

function my_pre_user_query( $q ){

    $limit = preg_replace( '/[^\d]/', '', $q->query_limit );

    $from   = 'WHERE 1=1';
    $to     = sprintf( 'WHERE Rand()<(SELECT ((%d/COUNT(*))*10) FROM %susers)', 
                        $limit, 
                        $GLOBALS['wpdb']->prefix 
             );

    $q->query_where   = str_replace( $from, $to, $q->query_where );
    $q->query_orderby = ' ORDER BY Rand() ';

    // remove the hook    
    remove_action( current_filter() , __FUNCTION__ );
}
3
birgire