J'ai 2 tables. 1 est la musique et 2 est Listentrack. Listentrack suit les jeux uniques de chaque chanson. J'essaie d'obtenir des résultats pour des chansons populaires du mois. Je reçois mes résultats mais ils prennent juste trop de temps. Ci-dessous mes tables et mes requêtes
430 000 lignes p> 12500 lignes p> Cette requête n'est pas très complexe Et les rangées ne sont pas trop grandes, je ne pense pas. P> Y a-t-il un moyen de vous accélérer? Ou pouvez-vous suggérer une meilleure solution? Cela va être un travail cron au début de chaque mois, mais j'aimerais également faire par les résultats de la journée. P> OH BTW Je l'exécute localement, plus de 4 minutes à courir, mais sur pousser, il faut environ 45 secondes p> p>
9 Réponses :
Essayez de créer un index qui aidera à la jointure:
Je suis plus d'un gars SQL Server, mais ces concepts doivent s'appliquer. P>
J'ajouterais des index: p>
Ces index devraient accélérer énormément la requête (j'avais à l'origine les noms de table mélangés - fixés dans la dernière modification). P>
Je crois que les noms de table d'index sont retournés. J'ai réussi à faire cela la première fois aussi et je l'ai attrapé juste avant de poster.
Thejacobtaylor avait raison, j'ai eu les noms de table à l'envers. J'ai réparé cela.
La question que j'ai, c'est pourquoi avons-nous les deux les avoir recouties? J'ai parcouru à travers le poteau, mais je n'ai pas vu le déclencheur que je me suis trompé.
Mon hypothèse est la suivante: dans l'introduction de la question, ils sont introduits en tant que musique puis listentrack, mais les requêtes de création montrent à Listentrack en premier.
Pour la plupart, vous devez également indexer toute colonne utilisée dans une jointure. Dans votre cas, vous devez indexer les deux @jeff s - un index music.Date_Created ne serait pas aidée parce que vous allez à travers un Fonction d'abord, MySQL ne peut pas utiliser un index sur cette colonne. Souvent, vous pouvez réécrire une requête de sorte que la colonne référencée indexée soit utilisée statiquement comme: p> devient p> ceci Filtrera la baisse des enregistrements de 2009-08-15 et permettra à tous les indices sur cette colonne d'être candidats. Notez que MySQL pourrait ne pas utiliser cet index, cela dépend d'autres facteurs. P> Votre meilleur pari est de créer un double index sur ces 2 index couvrira cette requête particulière. p> Notez que si vous exécutez En général, vous devez toujours exécuter votre requête sous http://dev.mysql.com/doc/refman/5.0/fr/Und-Explain.html P> P> listentrack.url code> et music.url code> listentrack (URL, date_created) code>
puis un autre index sur musique.url code> p> Expliquer code > Sur cette requête, vous allez toujours obtenir un à l'aide de FilesTort code> car il doit écrire les enregistrements à une table temporaire sur le disque pour effectuer la commande par. P> Expliquer code> pour avoir une idée sur la manière dont MySQL exécutera la requête puis passer de là. Voir le Expliquer code> Documentation: P>
Chronométrage brutal. :) Excellente réponse. Battez-moi en quelques secondes.
Merci beaucoup semble très utile. Je vais suivre votre lien et lire et essayer votre exemple
Je pense que j'ai peut-être manqué l'évidence avant. Pourquoi rejoignez-vous la table de musique du tout? Vous ne semblez pas utiliser les données de cette table et vous effectuez une jointure gauche qui n'est pas requise, non? Je pense que cette table étant dans la requête rendra beaucoup plus lente et n'ajoutera aucune valeur. Prenez toutes les références à la musique, à moins que l'inclusion de l'URL n'est requise, auquel cas vous avez besoin d'une jointure droite pour le forcer à ne pas inclure une ligne sans valeur correspondante. P>
J'ajouterais de nouveaux index, comme les autres mentionnent. Spécifiquement j'ajouterais: URL de la musique LISTENTRACK DATARE_CREATED, URL P>
Cela améliorera votre jointure une tonne. p>
Ensuite, je regarderais la requête, vous forcez le système pour effectuer des travaux sur chaque rangée de la table. Il serait préférable de reformuler la restriction de date comme une plage. P>
Pas sûr de la syntaxe de la tête de la tête: Où '2009-08-15 00:00:00' <= Date_Créré <2009-08-16 00:00:00 P>
Cela devrait permettre d'utiliser rapidement l'index pour localiser les enregistrements appropriés. L'indice combiné à deux clés sur la musique devrait permettre de trouver les enregistrements basés sur la date et l'URL. Vous devriez expérimenter, ils pourraient mieux aller d'aller dans l'URL d'une autre direction, Date_Créré sur l'index. P>
Le plan d'explication de cette requête doit dire "à l'aide d'index" sur la colonne de droite pour les deux. Cela signifie qu'il n'aura pas besoin de toucher les données dans le tableau pour calculer vos sommes. P>
Je vérifierais également les paramètres de mémoire que vous avez configurés pour MySQL. On dirait que vous n'avez pas assez de mémoire alloué. Soyez très prudent sur les différences entre les paramètres de serveur et les paramètres basés sur le thread. Le serveur avec un cache de 10 Mo est assez petit, un thread avec un cache de 10 Mo peut utiliser rapidement beaucoup de mémoire. P>
jacob p>
J'utilise des données dans cette table, mais je déboguais là où vient la lenteur. Pas de jointure 1 sec requête. Inscrivez-vous après l'ajout de l'index IDX sur la musique.url a couru à 7 secondes et ajout de musique.Plays la poussé jusqu'à 10
Pouvez-vous poster le plan d'explication pour la "vraie" requête ou celle avec l'index? Combien d'enregistrements parlons-nous pendant une journée (ordre de grandeur)? Combien de mémoire utilisez-vous sur la boîte? Index et cachets de données, ou juste cache sur InnoDB, sont essentiels et faciles à réparer.
Après que vous ajoutez des index, vous voudrez peut-être explorer l'ajout d'une nouvelle colonne pour que la date_créated soit un UNIX_TMESTAMP, qui fera des opérations de mathématiques plus rapides. P>
Je ne suis pas certain pourquoi vous avez la fonction DIFF, comme il apparaît, vous recherchez toutes les lignes mises à jour à une date donnée. P>
Vous voudrez peut-être regarder votre requête car il semble avoir une erreur. P>
Si vous utilisez des tests d'unité, vous pouvez comparer les résultats de votre requête et une requête à l'aide d'un horodatage UNIX à la place. P>
Pourquoi répétez-vous l'URL dans les deux tables? p>
Demandez à la liste de Listentrack. Se débarrasse de la recherche de texte ainsi que de l'index supplémentaire. P>
En plus, il est sans doute plus correct. Vous suivez les temps où une piste particulière a été écoutée, pas l'URL. Et si l'URL change? P>
Vous voudrez peut-être ajouter un index au champ URL des deux tables. P>
Cela dit, lorsque je suis converti de MySQL en SQL Server 2008, avec les mêmes requêtes et les mêmes structures de base de données, les requêtes ont couru 1 à 3 ordres de grandeur plus rapidement. P>
Je pense que certains d'entre eux ont eu à voir avec les SGBDM (optimiseurs MySQL ne sont pas si bons ...) et certains d'entre elles auraient pu faire avec la manière dont les ressources du système de réserve de RDBMS. Bien que les comparaisons ont été effectuées sur des systèmes de production où seul le DB fonctionnerait. P>
Pré-regroupement puis rejoindre rend les choses beaucoup plus rapidement avec MySQL / Myisam. (Je suis suspect moins de ceci est nécessaire avec d'autres dB)
Ceci devrait fonctionner aussi vite que la version non jointe: p>
Ceci ci-dessous fonctionnerait probablement pour accélérer la requête. p>
Créer index music_url_index sur la musique (URL) à l'aide de BTREE; Créer Index Listentrack_url_Index sur Listentrack (URL) à l'aide de BTREE; P>
Vous devez vraiment connaître le nombre total de comparaisons et de balayages de ligne qui se produisent. Pour obtenir cette réponse, regardez le code ici de la façon de faire cela en utilisant Expliquer http: / /www.siteconsortium.com/h/p1.php?id=MYSQL002 . P>