-2
votes

Optimiser le nombre (*)

J'ai une table éléments code> à partir duquel je sélectionne 40 lignes à une heure ordonnée par la popularité code> de l'élément.

the la popularité code> est simplement téléchargements / impressions code>; p>

Query strong>: 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;


7 commentaires

Votre code n'est pas syntaxiquement correct. Il n'y a pas de table appelée éléments 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.


3 Réponses :


1
votes

Je pense que la requête suivante peut résoudre votre problème: xxx

se soucie également de téléchargements et impressions sont indexés par champ d'élément.


1 commentaires

@Guidev - Quelle version de mysql? Il y avait une amélioration significative à un moment donné lorsque rejoint deux tables dérivées.



1
votes

non résolvable avec cette approche.

Il y a deux solutions:

  • garde des compteurs (par item.id ) pour impressions et téléchargements.
  • TABLES RÉSULTATS.

    compteurs Cela implique d'ajouter une colonne supplémentaire pour chaque compteur à la table (code>. Ou construire une table parallèle avec ID et les différents compteurs. Pour vraiment haut volume de comptes, ces derniers évitent des affrontements entre diverses requêtes.

    Tableaux récapitulatifs Construire et augmenter progressivement une table (s) qui résume les comptes comme ceux-ci, plus peut-être autre SUMS , comptent , 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.

    Plus sur les tableaux récapitulatifs: http://mysql.rjweb.org/doc.php/ Tableau sommaire


0 commentaires

0
votes

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


2 commentaires

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 est la touche principale , d'où l'évolution de l'évidence unique (id) .