2010-07-27 6 views
1

Je suis assez nouveau dans le SQL et j'ai besoin d'aide pour certaines tâches. J'ai une requête qui est appelée par notre code Flex/Java qui joint plusieurs tables pour obtenir des informations. Lors de l'exécution d'une analyse d'analyse, j'ai vu que la requête prend plus de 15 minutes, ce qui arrive parfois même si le site est soumis à un trafic intense. Ce que j'essaie de faire est de créer une règle, ou un déclencheur, qui voit si la requête est appelée et sélectionne les données de la table de vue matérialisée à la place. J'ai essayé d'implémenter une règle pour cela, mais j'avais du mal quand j'ai reçu des erreurs en essayant de joindre plusieurs tables dans la règle. Essentiellement, y a-t-il un moyen, que ce soit une règle, un déclencheur ou quoi que ce soit d'autre, de voir si une certaine requête est exécutée et que je peux remplacer cette requête par une autre d'une autre table? Merci d'avance.Comment réécrire une requête dans PostgreSQL 8.3

Exemple de la requête:

select 
    player_id, 
    player_names, 
    player_level, 
    current_location 
from 
    server_info 
    join players using (player_id) 
    join locations using (location_id) 
where 
    current_location = 'Central Hub' 
+2

Alors ... vous voulez détecter si une requête spécifique est exécutée, l'arrêter et injecter une requête différente dans la même session sans que le programme d'apblication ne s'en aperçoive? Ce n'est pas une réécriture de requêtes, c'est ... Je ne sais pas comment l'appeler, mais je suis à peu près certain que ce n'est pas la bonne façon de résoudre le problème. Ne pouvez-vous pas mieux formuler la requête, puis modifier le point dans l'application où il est émis? –

+2

Cela ne semble pas une requête terriblement complexe. Êtes-vous sûr que ce n'est pas seulement un problème d'indexation sur les tables? En supposant que les jointures sont sur FK et peut-être un index sur current_location, cette requête devrait être assez rapide. –

+0

Nous avons une base de données assez volumineuse et nous sommes actuellement en train de tout transférer vers de nouveaux serveurs et éventuellement de refaire la majorité de la base de données. Le problème est que nous avons deux applications distinctes, une pour le client et une pour l'administrateur, et seule l'application administrateur est capable d'obtenir les informations sur le serveur. Nous avons essayé de le faire dans notre propre code Flex, mais le projet a été corrompu et nous n'avons pas besoin de temps ni de ressources pour installer une nouvelle application Flex. Nous avons donc pensé qu'une règle serait un substitut rapide. Ce n'est pas la bonne réponse, mais temporaire. – Seb

Répondre

2

Pourquoi ne pas simplement changer l'application à la source la vue matérialisée si c'est ce que vous voulez? Il n'y a aucun moyen de réécrire une jointure complexe pour la source d'une table non liée - que je connais. Et, si vous pouviez faire, vous voulez vraiment avoir du vaudou profond comme ça dans votre système de planification/de requête? SQL VIEW s sont implémentés avec un SELECT RULE, mais cela ne vous permet pas de passer de la requête complexe à la vue matérialisée. Il vous obtient de TABLE1, à TABLE2.

Une meilleure question serait quels sont les types de player_id et location_id, sont-ils à la fois int et ils ont tous deux btree indices? Est-ce que current_location est indexé et est-il utilisé pour l'égalité, la regex ou les conditions LIKE? Quelle version de Postgresql utilisez-vous? Pouvez-vous joindre un EXPLAIN ANALYZE de la requête qui provoque le temps d'attente massif?

+0

le player_id et le location_id sont tous deux int, ils n'ont pas d'index btree, et le location_id est indexé. La requête utilise des conditions d'égalité. Le serveur utilise la version 8.3 et j'ai juste essayé d'exécuter une analyse d'explication et elle a expiré. Pratiquement nous essayons de trouver un moyen de passer de la requête complexe à la vue matérialisée, mais nous essayons de le faire à partir de la base de données elle-même puisque nous ne pouvons pas reconstruire l'application en raison de fichiers corrompus. – Seb

+1

Vous devez avoir les index 'btree' dans' player_id' et 'location_id' ** DANS LES DEUX TABLES **, ou votre requête sera lente comme de la saleté. Entrer dans psql et attacher la sortie de '\ d server_info',' \ d players', et '\ d locations' (découper la description de la table au-dessus du mot * Index: *), aussi UTILISER est un test de qualité (raccourci) , ainsi que 'current_location = 'Central Hub'' de votre exemple, veuillez donc répondre à nouveau, * Est-ce que current_location est indexé, et est-il utilisé pour l'égalité, regex ou LIKE conditionals?* –

+0

La table des localisations a l'ID_location, qui est un entier indexé, l'emplacement_courant, qui est juste un champ de texte indiquant le nom de la ville, et une carte, autre champ de texte utilisé pour spécifier le fichier de carte à charger . D'après ce que vous m'avez dit, il semble que l'application exécute des requêtes utilisant des conditions d'égalité. Je ne peux pas joindre la sortie car je n'ai pas d'accès direct à PostgreSQL. Je n'ai accès qu'à l'application et aux journaux de requêtes générés à partir de l'application. Je m'excuse de ne pas pouvoir aider beaucoup. – Seb

Questions connexes