2009-10-28 4 views
0
SELECT DISTINCT group_id 
     , supplier_id 
     , supplier_name 
     , site_division_id 
     , site_division_name 
FROM view_supplier_site 
WHERE supplier_id IN (SELECT DISTINCT supplier_id 
         FROM view_supplier 
         WHERE YEAR IN (2008, 2009) 
         AND received_quantity > 0 
         AND COE_SUPPLIER NOT IN ('X - LG', 'Y - LG', 'Z - LG')) 
+0

Le redouté DISTINCT. La question la plus pertinente serait, pourquoi pensez-vous que la déclaration doit être refactorisée? –

+1

Rien à redire avec 'DISTINCT' - expliquer le plan montrera qu'il est identique à l'utilisation de' GROUP BY'. –

+0

Cette déclaration prend beaucoup de temps pour que le résultat apparaisse. Je voulais juste savoir si c'est un problème avec l'instruction SQL ou est-ce dû au grand nombre d'enregistrements dans la table ??? – HanuAthena

Répondre

4

non sous-requête Affacturage:

SELECT vss.group_id, 
     vss.supplier_id, 
     vss.supplier_name, 
     vss.site_division_id, 
     vss.site_division_name 
    FROM view_supplier_site vss 
    JOIN (SELECT vs.supplier_id 
      FROM view_supplier vs 
      WHERE vs.year IN (2008, 2009) 
      AND vs.received_quantity > 0 
      AND vs.coe_supplier NOT IN ('X - LG', 'Y - LG', 'Z - LG') 
     GROUP BY vs.supplier_id) s ON s.supplier_id = vss.supplier_id 
GROUP BY vss.group_id, vss.supplier_id, vss.supplier_name, vss.site_division_id, vss.site_division_name 

En utilisant l'affacturage sous-requête:

WITH suppliers AS (
    SELECT vs.supplier_id 
     FROM view_supplier vs 
    WHERE vs.year IN (2008, 2009) 
     AND vs.received_quantity > 0 
     AND vs.coe_supplier NOT IN ('X - LG', 'Y - LG', 'Z - LG') 
    GROUP BY vs.supplier_id) 
    SELECT vss.group_id, 
     vss.supplier_id, 
     vss.supplier_name, 
     vss.site_division_id, 
     vss.site_division_name 
    FROM view_supplier_site vss 
    JOIN suppliers s ON s.supplier_id = vss.supplier_id 
GROUP BY vss.group_id, vss.supplier_id, vss.supplier_name, vss.site_division_id, vss.site_division_name 

Ils sont équivalents. Comme je peux le voir, il n'y a pas beaucoup d'optimisation à faire. La prochaine chose à regarder serait index ...

+0

ouah !! tapote sur ton dos, mec. Votre 'Non Sous-requête' a juste pris 3.5sec (avg) pour s'exécuter pendant que le mien prenait environ 14sec. – HanuAthena

+0

Je m'attends à ce qu'ils optimisent à peu près le même plan d'exécution, autre que l'utilisation de DISTINCT (que le CBO appliquerait probablement à la sous-requête dans la demande de l'OP si elle n'était pas spécifiée). Il serait intéressant de voir les plans d'exécution pour les requêtes de 3,5 secondes et de 14 secondes pour comprendre où se trouve la différence. –

1

Je vous suggère ce qui suit:

  • Au lieu d'utiliser un IN, utilisez une jointure interne (probablement pas une amélioration de la performance, mais les regards de déclaration " plus belle ")
  • Cela vous permettra de vous débarrasser de la DISTINCT sur view_supplier (encore une fois, probablement pas de différence de performance)
  • est le DISTINCT sur view_supplier nécessaire? Il y a des identifiants qui peuvent être des clés pour supplier_site.
  • NOT IN peut être un problème de performance .. pouvez-vous changer cela en quelque chose d'autre comme <'X - LG' ou alors?
  • Si les vues sont plus que des "alias" pour les tables/colonnes de base, il peut y avoir des façons d'utiliser les tables sous-jacentes.
  • Une autre chose à regarder serait des index.
  • YEAR est-il une colonne calculée? Si elle est juste YEAR(datevalue) il peut être plus rapide d'utiliser quelque chose comme datevalue between <Jan1st> and <Dec31>

La plupart de ces changements seraient cosmétiques, les domaines sur quoi se concentrer serait déterminé par les problèmes que vous voyez avec l'énoncé.

Questions connexes