Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/09/2008, 15h10   #1
Invité régulier
 
Inscription : juin 2007
Messages : 39
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 39
Points : 8
Points : 8
Par défaut Optimisation d'une requête

Bonjour,

J'ai créé une requete sql, mais elle me semble un peu lourde à l'exécution, je me demandais si il en existait une forme "optimisée".
Cette requete sera exécutée en shell.

Code :
SELECT a,b,(a/b*100) FROM (((SELECT count(*) AS a FROM drive WHERE argument = 'OK') ra), ((SELECT count(*) AS b FROM drive) rb))
Merci d'avance
mitou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 15h23   #2
Scorpi0
Invité(e)
 
Messages : n/a
Détails du profil
Informations forums :
Messages : n/a
Points : 0
Bonjour,

Commence par bien indenter a requête !!
  Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 15h29   #3
Invité régulier
 
Inscription : juin 2007
Messages : 39
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 39
Points : 8
Points : 8
OK je vais tenter d'indenter ma requete:

Code :
1
2
3
4
SELECT a,b,(b/a*100) FROM(
     ((SELECT count(*) AS b FROM centreon.host WHERE host_register = "1") ra),
     ((SELECT count(*) AS a FROM centreon.host) rb)
)
mitou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 15h33   #4
Membre expérimenté
 
Inscription : juillet 2007
Messages : 495
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juillet 2007
Messages : 495
Points : 585
Points : 585
Ca n'est pas étonnant que ce soit lourd : tu n'as pas de jointure entre tes 2 sous-requêtes ra et rb, donc tu fais un produit cartésien.
Pour être lourd, ça doit être du très lourd, même pas besoin d'avoir des tables très volumineuses, et en plus fonctionnellement ça n'a certainement aucun sens !
__________________
Des chercheurs qui cherchent, on en trouve, mais des chercheurs qui trouvent, on en cherche !
dgi77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 15h36   #5
Scorpi0
Invité(e)
 
Messages : n/a
Détails du profil
Informations forums :
Messages : n/a
Points : 0
Le produit cartésien ne se fait que sur 2 tables d'une ligne, rien de bien méchant donc.

Pas moins lourd mais plus joli je trouve :

Code :
1
2
3
4
5
6
7
8
9
WITH 
t1 AS (SELECT count(*) AS a FROM drive),
t2 AS (
        SELECT count(*) AS b
        FROM drive 
        WHERE argument = 'OK'
      ) 
SELECT a, b, (a/b)*100
FROM t1, t2
Une question de gout ^^
Tu as combien de ligne dans ta table ? Quel proportion de argument = 'OK' ?


Une autre idée, si ça te dérange pas d'avoir ton résultat en lignes plutôt qu'en colonne :

Code :
1
2
3
SELECT count(1), decode(argument, 'OK', 'OK', 'NOT OK')
FROM drive 
GROUP BY decode(argument, 'OK', 'OK', 'NOT OK')

Dernière modification par Scorpi0 ; 10/09/2008 à 15h46.
  Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 15h45   #6
Invité régulier
 
Inscription : juin 2007
Messages : 39
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 39
Points : 8
Points : 8
Dans ma table je dois avoir dans les 20 lignes.

Et la proportion d'état "OK", un maximum j'espère, sauf gros soucis technique...


Citation:
Envoyé par dgi77 Voir le message
Ca n'est pas étonnant que ce soit lourd : tu n'as pas de jointure entre tes 2 sous-requêtes ra et rb, donc tu fais un produit cartésien.
Pour être lourd, ça doit être du très lourd, même pas besoin d'avoir des tables très volumineuses, et en plus fonctionnellement ça n'a certainement aucun sens !
Merci de l'information, mais si je post ici, c'est que j'ai bien conscience du problème. Je ne cherche pas des critiques, mais plutôt des conseils. Donc si suite à ta jolie démonstration de la nullité de ma requete tu avais également quelques solutions à proposer, je suis également preneur.
mitou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 15h56   #7
Scorpi0
Invité(e)
 
Messages : n/a
Détails du profil
Informations forums :
Messages : n/a
Points : 0
Pour remettre en lignes la requête que je t'ai postée au dessus, tu peux faire un truc de ce genre :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
WITH myTable AS
(
  SELECT count(1) AS n, decode(argument , 'OK', 'OK', 'NOT OK') AS etat
  FROM drive 
  GROUP BY decode(argument , 'OK', 'OK', 'NOT OK')
)
SELECT nOK, nNOTOK, nOK/nNOTOK*100
FROM
(
  SELECT DISTINCT (SELECT n FROM myTable WHERE etat = 'OK') AS nOK, 
             (SELECT n FROM myTable WHERE etat = 'NOT OK') AS nNOTOK
  FROM myTable
)
Y'a des fonctions pivots à partir d'Oracle 11g, mais ça je connais pas encore ^^

Au final, si ta table ne fait que 20 lignes et n'est pas destinée à en contenir plus, ta toute première requête devrait largement suffire. Tu te poses pas des questions pour optimiser des requête qui tape 20 lignes.
Si tu trouves ton temps d'exécution trop lent, le problème doit venir d'ailleurs.
  Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 16h20   #8
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par mitou Voir le message
Dans ma table je dois avoir dans les 20 lignes.
Si en exécutant une requête sur 20 lignes tu as déjà des soucis de perfs, le problème vient surement d'ailleurs

Tu n'utiliserais pas un site web ou excel ou autre pour voir le résultat plutôt que SQL*Plus ?
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/09/2008, 12h36   #9
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
Un seul accès à la table suffit :
Et il faut gérer le cas où centreon.host ne contient aucune ligne.
Code :
1
2
3
SELECT COUNT(*) a, SUM(DECODE(host_register, '1',1, 0)) b, 
	DECODE(COUNT(*), 0,NULL,  SUM(DECODE(host_register, '1', 1,0)) / COUNT(*) * 100) AS pct
FROM centreon.host
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h32.


 
 
 
 
Partenaires

Hébergement Web