J'ai une table the Query strong>: p> éléments code> à partir duquel je sélectionne 40 lignes à une heure ordonnée par la popularité code> de l'élément. la popularité code> est simplement téléchargements / impressions code>; p> CREATE TABLE `items` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(35) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24369 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `impressions` (
`item` int(10) unsigned NOT NULL,
`user` char(36) NOT NULL DEFAULT '',
PRIMARY KEY (`item`,`user`),
CONSTRAINT `impression_ibfk_1` FOREIGN KEY (`item`) REFERENCES `items` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `downloads` (
`item` int(10) unsigned NOT NULL,
`user` char(36) NOT NULL DEFAULT '',
PRIMARY KEY (`item`,`user`),
CONSTRAINT `download_ibfk_1` FOREIGN KEY (`item`) REFERENCES `items` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3 Réponses :
Je pense que la requête suivante peut résoudre votre problème: se soucie également de téléchargements code> et impressions code> sont indexés par champ d'élément. p> p>
@Guidev - Quelle version de mysql? Il y avait une amélioration significative à un moment donné lorsque rejoint code> deux tables dérivées.
non résolvable avec cette approche. P>
Il y a deux solutions: P>
item.id code>) pour impressions et téléchargements. Li>
- TABLES RÉSULTATS. LI>
ul>
compteurs strong> Cela implique d'ajouter une colonne supplémentaire pour chaque compteur à la table code> (code>. Ou construire une table parallèle avec ID code> et les différents compteurs. Pour vraiment haut volume de comptes, ces derniers évitent des affrontements entre diverses requêtes. P>
Tableaux récapitulatifs forts> Construire et augmenter progressivement une table (s) qui résume les comptes comme ceux-ci, plus peut-être autre SUMS code>, comptent code>, etc. La table serait peut-être complétée quotidiennement pour les informations de la journée précédente. Ensuite, la "somme des comptes" pour obtenir le total du total; Ce sera beaucoup plus rapide que votre requête actuelle. P>
Plus sur les tableaux récapitulatifs: http://mysql.rjweb.org/doc.php/ Tableau sommaire p>
Je compterais d'abord les téléchargements et les impressions, puis obtenez le top 40:
create unique index idx1 on items(id); create index idx2 on downloads(item); create index idx3 on impressions(item);
Eh bien, maintenant que je le regarde, ma réponse n'est pas si différente de celle de Slava Rojnev et que vous dites que leur approche est toujours trop lente. Dans ce cas, vous voudrez peut-être suivre l'approche de l'entrepôt de données suggérées par Rick James.
Vraisemblablement ID code> est la touche principale code> code>, d'où l'évolution de l'évidence unique (id) code>.
Votre code n'est pas syntaxiquement correct. Il n'y a pas de table appelée
éléments code> dans la requête. Vos définitions de table ne sont pas non plus correctes, par rapport aux colonnes non dans la table.Ouais; ce n'est pas ta requête
Vous pouvez essayer avec une vue matérialisée. Ici, il y a une description semblable à votre problème: FUTDULY.COM/MYSQL-Materialized-Vues4/a >
@Gordonlinoff oui, désolé ... corrigé-le maintenant
@NicolalePetit Ouais, il y a un inconvénient avec cette approche: pour les nouveaux articles, le score serait nul pendant une période relativement longue. De plus, le temps de mettre à jour la table "Count" serait assez long, ne bloquerait pas toute la table, bloquant ainsi la requête principale pendant quelques minutes?
@Guidev. Je suis plus dans Postebrsql Tham MySQL. Vous pouvez utiliser le commutateur simultanément, pour résoudre le problème: Postgresql.org/docs/ 12 / SQL-RafrofluMaterializedView.html . Fondamentalement, vous créez une vue parallèle et, quand il est prêt, vous passez à la mise à jour.
Je viens de relire votre demande. "Il faut pour toujours pour compléter" et "allant de 2 à 10 secondes"? Je ne considère pas ce lent du tout. Vous regroupez et agrégez toutes les lignes dans deux tables, puis rejoignez-les, puis triez et classez-les, puis rejoignez-les à nouveau. Cela prend du temps bien sûr. Ce que vous recherchez, ce serait un entrepôt de données avec des données pré-agrégées.