web-dev-qa-db-fra.com

Efficacité d'affichage des auteurs aléatoires sur une base de données volumineuse

J'essaie d'afficher une liste de 5 auteurs de manière aléatoire . Voici quelques solutions que j'avais trouvées:

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

J'utilise actuellement l'ancienne solution, sauf que j'utilise WP_User_Query comme suit:

$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);

Cependant, pour ma compréhension amateur , ceci ira chercher la liste complète des utilisateurs . Donc, je me demandais si j'avais environ 2000-5000 utilisateurs (ou plus) , cela affectera-t-il le chargement de la page ? Comment puis-je rendre cela plus efficace?

UPDATE:

De même, array_Rand() serait-il une méthode plus efficace par rapport à shuffle()?

2
Giraldi

Si l'efficacité vous préoccupe, vous pouvez utiliser l'API Transients pour stocker la requête. Stocker quelque chose que vous souhaitez randomiser peut sembler contre-intuitif, mais si vous stockez toute la requête, vous pouvez toujours randomiser et manipuler le tableau résultant pour obtenir les résultats souhaités.

Voici comment obtenir tous les abonnés et les stocker dans un transitoire, avec un mais de droite PHP à la fin pour mélanger/randomiser le résultat et ensuite sélectionner les 5 premiers résultats avec array_slice()

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 );

et ensuite pour nous assurer que le transitoire est à jour, nous le supprimerons lorsqu'un utilisateur est mis à jour ou ajouté:

// 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

Vous ne voulez pas aller chercher tous les utilisateurs si vous avez seulement besoin de 5.

Si vous souhaitez utiliser WP_User_Query() pour extraire 5 utilisateurs par hasard, vous pouvez utiliser le crochet pre_user_query pour écraser la partie 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__ );
}

Mettre à jour:

Cet article contient une astuce pour réduire le nombre de lignes, en utilisant une condition WHERE spéciale, avant que la fonction ORDER BY Rand() ne se déclenche ... pour autant que je sache il.

La condition WHERE dans votre cas pourrait être

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

Donc, si vous avez un très grand nombre d'utilisateurs, vous pouvez alors essayer ce rappel d'action modifié:

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__ );
}

si l'astuce de l'article ci-dessus fonctionne!

Voici une version plus générale du rappel modifié:

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