Oracle
 sql >> Base de données >  >> RDS >> Oracle

Efficacité du calcul trimestriel des effectifs

Semble être une bonne variante au cas où il y aurait un index sur au moins effective_start_date et effective_end_date champs de per_all_people_f tableau.

La variante idéale pour cette requête est

create index x_per_all_people_search on per_all_people_f(   
  effective_start_date,
  effective_end_date, 
  person_id,  
  emp_flag
)

mais il peut être trop coûteux à maintenir (coût du disque, vitesse d'insertion).

De plus, le curseur dans le corps du package doit contenir une sous-requête et réutiliser les résultats d'appel de fonction :

cursor cur_var
is 
  select 
    EMP_2012,
    EMP_2013,
    (EMP_2013 - EMP_2012) Diff
  from (
   select 
     function_name('01-MAR-2012','31-MAY-2012') EMP_2012,
     function_name('01-MAR-2013','31-MAY-2013') EMP_2013
   from dual
  );

Bien sûr, la meilleure solution consiste à minimiser les changements de contexte et à obtenir toutes les valeurs à partir d'une seule requête SQL. De plus, vous pouvez fournir des paramètres directement au curseur :

cursor cur_var(
  start_1 date, end_1 date, 
  start_2 date, end_2 date
)
is 
  select 
    EMP_2012,
    EMP_2013,
    (EMP_2013 - EMP_2012) Diff
  from (
   select 
     (
       select 
         count(distinct papf.person_id)
       from 
         per_all_people_f papf
       where 
         papf.emp_flag = 'Y'
         and 
         effective_start_date >= trunc(start_1)
         and 
         effective_end_date   <= trunc(end_1)
     ) EMP_2012,
     (
       select 
         count(distinct papf.person_id)
       from 
         per_all_people_f papf
       where 
         papf.emp_flag = 'Y'
         and 
         effective_start_date >= trunc(start_2)
         and 
         effective_end_date   <= trunc(end_2)
     ) EMP_2013
   from dual
  );

De mon point de vue, les paramètres de fonction/curseur sont trop génériques, il serait peut-être préférable de créer un wrapper qui prend comme paramètres d'entrée le numéro de trimestre et deux années à comparer.

Et enfin, si les résultats prévus pour être utilisés en PL/SQL (je suppose qu'en raison du retour d'une seule ligne) n'utilisent pas du tout le curseur, renvoyez simplement les valeurs calculées via les paramètres de sortie. D'un autre point de vue, si vous avez besoin d'obtenir des données trimestrielles pour une année complète dans un seul curseur, il peut être plus efficace de compter tous les trimestres et de les comparer en une seule requête.