0
votes

Améliorer une requête inefficace

J'ai un problème sur lequel mon application achemine, car la requête prend trop de temps. J'utilise le niveau libre de Heroku, donc je ne reçois pas exactement une priorité à la vitesse et que je reçois des délais d'attente que je ne vois pas localement. J'espérais que quelqu'un pouvait voir une question avec ma requête qui me permettrait de renverser les choses.

Ma requête ressemble à ceci: xxx

Mes données sont composées de recettes stockées dans un fichier CSV. Il y a environ 300 rangées qui ressemblent à ceci: xxx


0 commentaires

3 Réponses :


2
votes

Vous essayez de faire trop dans un seul cycle de requête / réponse HTTP. Pour chaque ligne de votre CSV, vous effectuez un insert SQL (avec dbuser.recipes.create ), une mise à jour (code> (avec DBRECIPIPE.SAVE ), ainsi qu'un SELECT (avec aliment.find_by_name (Alimentation) ).

Même si vous effectuez des optimisations, êtes-vous sûr que le CSV n'aura que ~ 300 rangées pour la vie de votre application? Et même si la réponse est oui, de manière générale, il est une bonne pratique de répondre à une action d'utilisateur le plus rapidement possible au lieu de les avoir regardé leur navigateur attendre une réponse.

Donc, je vous recommande de repenser votre approche. Si une seule action doit exécuter de nombreuses commandes SQL, réfléchissez à la tâche de faire fonctionner de manière asynchrone. Voici quels outils tels que actifjob ( https://geguides.rubyonRails.org/ actif_job_basics.html ) et Sidekiq ( https://github.com/mperham/dekiq/) ont été conçus pour.

Par exemple, concevez votre application de manière à ce qu'un utilisateur clique sur un bouton de téléchargement du CSV et de répondre avec: «Merci pour votre soumission, nous y travaillons!". L'utilisateur pourrait toujours revenir et vérifier l'état du fichier en cours de traitement ou actualiser l'écran. Ou vous pouvez obtenir plus sophistiqué et automatiser les contrôles d'état avec la communication AJAX ou la communication bidirectionnelle via WebSockets. Le moyen railsy de faire cela serait avec ActionCable ( https: // guides. rubyonrails.org/action_cable_overview.html ).


2 commentaires

J'utilise cela comme moyen de semer ma base de données Prod à partir d'un CSV le produit est produit par un schéma Web. Il suffit de se produire une fois à Blue Moon comme je développe l'application et la page n'est accessible que pour moi. Après avoir fini le développement, je n'utiliserai plus cette méthode.


Vous devez utiliser des semences de base de données, il ne vous montrera pas le temps lorsqu'il s'exécute dans l'arrière-plan sur les rails de commande DB: graine



1
votes

Ce n'est pas vraiment une requête, c'est un tas d'autres choses. Vous analysez un fichier et écrivez à la base de données basée sur le contenu de ce fichier. En outre, si tout ce que vous faites, c'est ensemencer la base de données, il n'y a aucune raison d'impliquer l'application ou le navigateur du tout. Cette tâche serait mieux accomplie via une tâche de râteau ou de la console de rails. Vous pouvez éviter le délai d'attente de la base de données en brisant les actions en pièces séparées, par exemple

  • chargez le fichier dans la mémoire
  • Pour chaque ligne du fichier, écrivez dans la base de données et enregistrez l'enregistrement

    Dans tous les cas, vous devriez prendre cet ensemencement de la DB de l'application entièrement.


0 commentaires

1
votes

Vous pouvez utiliser un ACTIVERCORD-Import GEM - Idée principale dont la charge est chargée de nombreux enregistrements Par une requête.

Vous devez spécifier les noms de colonne sous forme de tableau: p> xxx pré>

suivant Vous devez charger les données de CSV dans la même commande: p>

DbIngredient.import(column_names, row_values)


0 commentaires