Je veux un classement groupé sur une très grande table, j'ai trouvé quelques solutions pour ce problème, par exemple. en this post et d'autres endroits sur le web. Je suis cependant incapable de comprendre la complexité la plus défavorable de ces solutions. Le problème spécifique consiste en une table où chaque ligne a un nombre de points et un nom associé. Je veux être en mesure de demander des intervalles de rang tels que 1-4. Voici quelques exemples de données:Classement en MySQL, comment obtenir les meilleures performances avec des mises à jour fréquentes et un grand ensemble de données?
name | points
Ab 14
Ac 14
B 16
C 16
Da 15
De 13
Avec ces valeurs suivantes « classement » est créé:
Query id | Rank | Name
1 1 B
2 1 C
3 3 Da
4 4 Ab
5 4 Ac
6 6 De
Et il devrait être possible de créer l'intervalle suivant sur de ID_requête: 2-5 dons rang: 1,3,4 et 4.
La base de données contient environ 3 millions d'enregistrements, donc si possible, je veux éviter une solution avec une complexité supérieure à log (n). Il y a constamment des mises à jour et des insertions sur la base de données, de sorte que ces actions devraient de préférence être effectuées aussi dans la complexité log (n). Je ne suis pas sûr que ce soit possible et j'ai essayé d'envelopper ma tête pendant un certain temps. Je suis arrivé à la conclusion qu'une recherche binaire devrait être possible mais je n'ai pas été capable de créer une requête qui fait cela. J'utilise un serveur MySQL.
Je vais élaborer sur la façon dont le pseudo-code pour le filtrage pourrait fonctionner. Tout d'abord, un index sur (points, nom) est nécessaire. En entrée, vous donnez un fromrank et un tillrank. Le nombre total d'enregistrements dans la base de données est n. Le pseudocode doit ressembler à ceci:
Trouver la valeur du point médian, compter les lignes inférieures à cette valeur (le nombre donne une estimation grossière du rang, sans tenir compte de celles ayant le même nombre de points). Si le nombre renvoyé est supérieur au délimiteur fromrank, nous subdivisons la première moitié et trouvons la médiane de celle-ci. Nous continuons à faire cela jusqu'à ce que nous soyons ciblés sur le nombre de points où fromrank devrait commencer. alors nous faisons la même chose dans la quantité de points avec l'index de nom, et trouvons la médiane jusqu'à ce que nous ayons atteint la rangée correcte. Nous faisons exactement la même chose pour tillrank.
Le résultat devrait être log (n) nombre de subdivisions. Donc, étant donné que la médiane et le compte peuvent être faits en temps de log (n), il devrait être possible de résoudre le problème dans le cas le plus défavorable du log de complexité (n). Corrigez-moi si je me trompe.
Heureux mon poste qui est pratique. Um, avez-vous essayé la deuxième solution? Utiliser group_concat? – achinda99
Je pense que cette méthode a de la complexité si je ne me trompe pas, sans compter que je ne vois pas comment elle peut être modifiée raisonnablement facilement pour permettre de récupérer n'importe quelle gamme de rangs. –
Malheureusement, le comte lui-même est ici l'opération la plus coûteuse, le temps dépendra des lignes effectivement comptés, et non sur les lignes recherchées, il sera toujours O (N) – Quassnoi