J'ai actuellement une liste de données présentant une liste de commandes générée au hasard. À l'heure actuelle, il n'y a pas de pagination, il est donc facile pour moi de générer une liste ordonnée au hasard. Comme ma liste de données grandit, il devient plus lent à cause de toutes les données, de sorte que la solution évidente est la pagination. La question que j'ai avec la pagination est que je ne peux pas générer de manière aléatoire la commande à chaque fois que la page charge, mon manager et moi sommes arrivés à la conclusion qu'une liste devra être pré-générée à l'avance et sera ré-générée chaque fois x la durée. Maintenant, le problème est comment stockons-nous cette liste générée? Il y a quatre options que nous avons proposées: p>
S'il y a d'autres solutions qui semblent mieux que des listes de temps pré-générées, j'aimerais entendre parler d'eux. P>
Merci. P>
mise à jour: une réponse que j'ai vraiment aimé, mais a été supprimée pour une raison quelconque, était que quelqu'un a mentionné l'utilisation d'une graine, puis je peux stocker la graine au lieu d'une liste d'identifiants, ce qui couperait mon stockage de données et tout simplifier. Je viens de tester la solution et cela fonctionne presque parfaitement. Le seul problème est que lorsque j'utilise la limite, tout va bousiller. Est-ce que quelqu'un a des suggestions à cela? Je ne veux pas avoir à générer toutes les données à chaque fois, je veux juste utiliser la limite * ,. Si j'utilise cela avec une graine, les chiffres sont toujours réinitialisés, comme il le devrait. P>
Espérons que cela a du sens. Cela a plus de sens que je pensais à cela que de la façon dont il s'est avéré typé. P>
6 Réponses :
Utilisez N ° 4, éventuellement stocké uniquement les identifiants des données à récupérer, dans l'ordre dans lequel elles doivent être récupérées. p>
meilleur que cela, si possible (puisque cela est similaire à un problème de mise à l'échelle), il est de pré-générer des données de chaque page. Par exemple, s'il est visionné uniquement via un navigateur, il suffit d'aller de l'avant et de pré-générer X-Nombre de pages statiques HTML (ou uniquement la partie Table / Liste). p>
Je sais que cela semble probablement ridicule sans autre explication, mais réfléchissez à l'une de ces options. p>
Également, si le serveur prend ce dur de la génération des résultats, il doit être séparé du serveur Web et éventuellement le rapport / génération exécuté sur un clone / esclave répliqué de la base de données d'origine. p>
J'aime me pencher plus vers le n ° 4 aussi parce que si nous utilisons des fichiers plats, nous allons prendre la même performance sur un travail cron, mais le fichier plat garantit que chaque fois que la liste pré-générée est générée, un utilisateur sera Sentez-vous que les performances ont frappé, alors qu'un travail de cron le fera en arrière-plan, et pour un utilisateur de sentir que les performances touchent, ils devraient entrer dans le site à ce moment précis que la base de données est mise à jour.
Je ne sais pas la fréquence à laquelle vous devez "mettre à jour" la liste générée, mais n'est-ce pas une option qui ne doit pas l'avoir générée à partir d'une base de données répliquée / esclave de quelque sorte, de sorte que la base de données "réelle" ne soit pas frappée du tout et donc les utilisateurs jamais i> avis? Est le goulot d'étranglement en CPU / commande aléatoire, ou ailleurs? Sais-tu?
MySQL Rand () accepte une graine comme argument facultatif. En utilisant une graine, il retournera le même résultat randomisé à chaque fois. P>
Ce que vous pouvez faire est de générer une graine aléatoire dans PHP sur la demande de première page et de la transmettre à chaque page à l'aide d'une chaîne de requête. P>
Edit: Désolé, je n'ai pas réalisé que la solution a déjà été publiée mais a été supprimée. em> p>
Yup, mais le problème avec cette solution, que j'aime, est que je ne peux pas limiter un nombre statique de résultats, de sorte que l'utilisateur passe dans les pages, une mauvaise efficacité commence à lancer. Un exemple est si je sélectionne Rand () De My_Table Limite 1, 5, je vais obtenir les mêmes résultats que Select Rand () de My_Table Limite 6, 5, qui serait assez aléatoire.
Pas sûr, semble fonctionner quand je l'ai testé. Dites-vous que les requêtes fonctionnent bien, mais ne sont pas efficaces?
Ce que je voulais dire, c'est que j'avais des problèmes avec certaines sections à l'aide de la limite. Mais je pense que je suis venu à une solution à ce stade. Ma solution utilise l'ID et une graine pour générer un numéro unique calculé de manière aléatoire. Cela me permettra de choisir du milieu. Je ferai plus de test, et si cela fonctionne, cette graine aléatoire sera la solution.
Je pourrais manquer quelque chose de très évident ici, mais n'est-ce pas le résultat souhaité? i.Imgur.com/5qdsa.png
Yup, c'est le résultat requis exact. Malheureusement, selon Geocar (Affiche ci-dessous), mon mysql pourrait avoir un bug. Je n'aime pas la mise à jour des serveurs en direct à moins que je ne dois, alors malheureusement, je vais devoir utiliser cette solution de contournement pour maintenant jusqu'à ce que je puisse trouver une bonne excuse pour mettre à jour les serveurs MySQL.
Utilisez un sous-sélection. De cette façon, vous pouvez toujours utiliser le rand () code> -trick, mais le décalage ne vous gâtera pas. mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 1;
+-------+
| id |
+-------+
| 24621 |
| 25214 |
| 27119 |
| 24672 |
| 25585 |
+-------+
5 rows in set (0.01 sec)
mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 2;
+-------+
| id |
+-------+
| 25214 |
| 27119 |
| 24672 |
| 25585 |
| 27718 |
+-------+
5 rows in set (0.01 sec)
mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 3;
+-------+
| id |
+-------+
| 27119 |
| 24672 |
| 25585 |
| 27718 |
| 25457 |
+-------+
5 rows in set (0.00 sec)
mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 4;
+-------+
| id |
+-------+
| 24672 |
| 25585 |
| 27718 |
| 25457 |
| 27112 |
+-------+
5 rows in set (0.01 sec)
mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 5;
+-------+
| id |
+-------+
| 25585 |
| 27718 |
| 25457 |
| 27112 |
| 24779 |
+-------+
5 rows in set (0.02 sec)
Rand () semble ignorer le décalage, ce qui est logique, car nous compensons x nombre de lignes, donc quoi que ce soit la première ligne générée sera la première parce que c'est lorsque la fonction Generate est appelée.
Johnathankong: Je viens de poster un exemple au contraire.
Je préfère le fichier aléatoire, surveillez cette classe de mise en cache à partir de OpenCart:
$cache = new cache();
$data = $cache->get('my_query_key');
if (!$data) {
// I do my query and I put it into an array (because I can use shuffle :P)
$result = mysql_query('SELECT * FROM items');
$data = array();
while($row = mysql_fetch_assoc($result)) { $data[] = $row; }
$cache->set('my_query_key', $data);
}
shuffle($data);
Utilisation de la graine est la solution de labest comme indiqué ci-dessus ...
En utilisant la logique suivante, vous pouvez "gâcher" vos données pour chaque visiteur séparé (en utilisant son IP) ainsi que de garder vos résultats de pagination pour Une bonne quantité de temps de navigation ... p> Avantages: rapide et facile, pas de charge supplémentaire, pas de cron nécessaire, aléatoire unique par visiteur. P> Inconvénients: Data remède si une heure (morelike), un changement de jour ou de mois pendant la navigation. P> p>
Voici ma solution de travail basée sur la réponse de Kevin: } p> acclamations. p> éditer: il s'agit d'un projet LARAVAVEL Basé, mais vous obtenez l'idée., em> p> p>
Êtes-vous sûr d'avoir besoin de pagination car toutes les données sont lentes, ou votre récupération actuelle est-elle lente? (La commande by rand () peut être un tueur de performance dans MySQL, par exemple, mais facilement évitée en seulement randomzing avec génération de script au lieu de la base de données). Si tout dans une page est encore plus souhaitable, la pagination optimise peut-être mieux, puis stocker des séquences prégénérées.
Nous utilisons Rand (), mais même si c'était efficace, le client souhaite toujours utiliser la pagination, car il est plus facile de parcourir des milliers de résultats.
J'ai un problème similaire avec la lenteur. La raison est que chaque profil d'utilisateur qui revient a une image de profil. Je préférerais paginer les résultats.
Mon commentaire est plus convivial que le développement, mais peut résoudre votre problème. Si les enregistrements que vous ramenez sont aléatoires, pourquoi se soucier de la page de page? Il suffit de retirer quelques-uns avec la clause limite, puis d'avoir un bouton sur la page qui vous permet de "remanier" ou de ce que vous voulez l'appeler.
Je suis d'accord avec @chris SOBOLEWSKI, dans le cas où une "page" donnée de données peut contenir des résultats des pages précédentes / autres. Est-ce le cas?
La question avec c'est que si elles continuent à aller à la page suivante, il y a un changement élevé qu'ils verront le même morceau de données sur chaque page, à moins que je n'imprime pas votre commentaire.
Je pense que vous avez compris. Ainsi, tandis que l'ordre du-data-dans-son-total est aléatoire, les données présentées sur chaque page doivent pas i> répéter les résultats précédemment observés, correct?
Exactement. C'est pourquoi je pense que je stocke les identifiants qui le rend compliqué.
L'utilisation d'une graine aléatoire est correcte, mais vous ne pourrez pas faire une nouvelle requête de limite sur chaque page, car elle obtiendra toujours des informations "nouvelles". Vous devrez choisir une méthode de "mémoriser" toute la liste, comme générés et l'étendez-la sur chaque page.