2011-09-28 1 views
2

Est-il possible d'envoyer une requête SELECT (coûteuse, mais peu prioritaire) à mySQL de telle sorte que si une requête UPDATE apparaît dans la file, mySQL met immédiatement fin à la requête, et le ré-ajouter à la fin de la file d'attente?Requête SELECT extrêmement basse en MySQL

Si ré-ajouter à la file d'attente n'est pas possible, je suis content de simplement supprimer la requête SELECT.

Répondre

2

Non, pas vraiment. Je ne sais pas exactement ce dont vous avez besoin, mais je suppose que vous devez soit optimiser le SELECT pour ne pas verrouiller une table entière, soit obtenir la réplication et faire le SELECT sur l'esclave plutôt que sur le maître.

Vous pourriez théoriquement savoir quel est l'identifiant de processus MySQL de la requête SELECT, et dans votre application envoyer un KILL avant toute mise à jour.

+0

Même si je ne verrouille qu'une partie de la table (ce que je vais devoir examiner), je déteste quand même risquer de retarder l'une de nos MISES À JOUR. Il s'agit d'une analyse de très faible priorité qui recherche des erreurs et collecte des statistiques.J'ai envisagé de faire l'analyse en morceaux en utilisant OFFSET et LIMIT, mais la réponse à une question précédente indique que c'est presque aussi cher qu'une analyse complète pour les OFFSET près de la fin de la table. http://stackoverflow.com/questions/7389759/memory-efficient-built-in-sqlalchemy-iterator-generator – Paul

+0

Je vais me pencher sur la réplication, mais elle semble être trop lourde car c'est une très grande table. Je préférerais simplement que la requête ne soit pas exécutée plutôt que de contenir une mise à jour. – Paul

+0

Peut-être que vous pouvez diviser votre requête, mais basé sur une colonne indexée et un champ WHERE – Evert

0

Eh bien, en quelque sorte peut-être.

Un client exécute une application qui jette occasionnellement des requêtes qui détruisent complètement les performances pour tout le reste sur le serveur. Nous avons un suivi et si nous avons une personne prête à réagir, nous pouvons traiter cette requête manuellement, et nous apprenons les problèmes de l'application en faisant les choses de cette façon. Mais pour éviter les pannes majeures si personne n'est sur la balle, nous avons un script automatisé qui met fin aux requêtes longues, de sorte que le serveur récupère dans le cas où personne n'est disponible pour intervenir dans les 15 minutes. Ce n'est pas l'idéal, mais c'est ce qui se passe actuellement dans le cadre de ce projet, et cela permet d'éviter les coupures prolongées occasionnelles qui se produisaient auparavant. Nous pouvons seulement nous déplacer si rapidement avec la résolution des problèmes. De toute façon, vous pouvez exécuter quelque chose de similaire, qui regarde les requêtes en cours d'exécution et reconnaît quand vous avez une mise à jour en attente sur l'un de vos grands choix, et dans ce cas, il tue le select. Faire ce genre de vérification quelques fois par minute n'est pas trop cher. Je voudrais faire un peu de test avant de courir. Donc, si vous pouvez résoudre votre problème de cette façon dépend de votre tolérance pour combien de temps une mise à jour peut être retardée. Exécuter ce chaque minute (comme nous le faisons) n'est aucun problème du tout. L'exécuter chaque seconde ajouterait sensiblement à la charge globale. Vous devez tester jusqu'où vous pouvez raisonnablement aller entre ces points. Cette approche signifie un certain délai avant que la sélection ne soit repoussée, mais cela vous évite d'avoir à construire cette logique dans potentiellement de nombreux endroits différents dans votre application.

-

En ce qui concerne la rupture de votre requête, vous êtes le plus susceptible de restreindre mieux les morceaux par plage identifiant d'une ou plusieurs tables dans votre requête plutôt que par décalage et limite.

-

Il peut aussi y avoir de bonnes solutions disponibles en fonction de partitionnement des tables afin que les requêtes n'entrent en collision pas aussi mal. Assurez-vous d'avoir une très bonne compréhension de ce que vous faites pour cela.