Olá a todos

Tenho trabalhado em um projeto de tuning de aplicação, que envolve análise
das queries através de planos de execução; uma das views que mais utilizo
para é a gv$sql_plan, que através de um join com a gv$sqlarea consigo
descobrir quais são os planos de execução em memória e quais estão sendo
utilizados.

Uma das coisas que me intrigam é o fato de que, as vezes, o Oracle
armazena o mesmo plano de acesso (inclusive com o mesmo custo) com Child
Numbers diferentes. Mas, o que é o Child Number? E, porque ele muda, sendo
que as vezes o plano de execução é o mesmo?

Por exemplo: A query abaixo traz todos os planos de execução em memória,
com custo e por instância, de uma certa query (identificada por
hash_value)
, e o plano que está em uso pelo Oracle
/*
(
    SELECT  DISTINCT (SP.CHILD_ADDRESS) ,
            SP.INST_ID,
            SP.CHILD_NUMBER,
            SP.HASH_VALUE,
            SP.PLAN_HASH_VALUE,
            MAX(SP.COST) CUSTO,
            MAX(SP.IO_COST) CUSTO_IO,
            MAX(SP.CPU_COST) CUSTO_CPU,
            '' STATUS
    FROM GV$SQL_PLAN SP
    WHERE HASH_VALUE = 3643588562
    GROUP BY SP.CHILD_ADDRESS, SP.INST_ID,CHILD_NUMBER, SP.HASH_VALUE,
SP.PLAN_HASH_VALUE
    MINUS
    SELECT  DISTINCT (SP.CHILD_ADDRESS) ,
            SP.INST_ID,
            SP.CHILD_NUMBER,
            SP.HASH_VALUE,
            SP.PLAN_HASH_VALUE,
            MAX(SP.COST) CUSTO,
            MAX(SP.IO_COST) CUSTO_IO,
            MAX(SP.CPU_COST) CUSTO_CPU,
            '' STATUS
    FROM GV$SQL_PLAN SP ,
         GV$SQLAREA SA
    WHERE SP.HASH_VALUE = 3643588562
      AND SP.CHILD_ADDRESS = SA.LAST_ACTIVE_CHILD_ADDRESS
    GROUP BY SP.CHILD_ADDRESS,
             SP.INST_ID,CHILD_NUMBER,
             SP.HASH_VALUE,
             SP.PLAN_HASH_VALUE)
UNION
  SELECT  DISTINCT (SP.CHILD_ADDRESS) ,
          SP.INST_ID,
          SP.CHILD_NUMBER,
          SP.HASH_VALUE,
          SP.PLAN_HASH_VALUE,
          MAX(SP.COST) CUSTO,
          MAX(SP.IO_COST) CUSTO_IO,
          MAX(SP.CPU_COST) CUSTO_CPU,
          'EM USO' STATUS
  FROM GV$SQL_PLAN SP ,
       GV$SQLAREA SA
  WHERE SP.HASH_VALUE = 3643588562
     AND SP.CHILD_ADDRESS = SA.LAST_ACTIVE_CHILD_ADDRESS
  GROUP BY SP.CHILD_ADDRESS,
        SP.INST_ID,
        CHILD_NUMBER,
        SP.HASH_VALUE,
        SP.PLAN_HASH_VALUE
  ORDER BY INST_ID,
           CHILD_NUMBER

*/

resultado:

/*
CHILD_ADDRESS       INST_ID CHILD_NUMBER HASH_VALUE PLAN_HASH_VALUE     
CUSTO   CUSTO_IO  CUSTO_CPU STATUS
---------------- ---------- ------------ ---------- ---------------
---------- ---------- ----------
000000024E1F0F20          1            0 3643588562      2999871912       
209        207   19905805
00000002234F3380          1            1 3643588562      2999871912       
209        207   19905804
0000000254DE3D00          1            2 3643588562      2999871912       
209        207   19905804 EM USO
000000022728E810          2            0 3643588562      2999871912       
209        207   19905804
000000019FCC8BD8          2            1 3643588562      2999871912       
209        207   19905804 EM USO
000000029AFACFA0          3            0 3643588562      2999871912       
209        207   19905805
00000002965FD790          3            1 3643588562      2999871912       
209        207   19905804
000000022AA0A328          3            2 3643588562      2999871912       
209        207   19905804
000000021D858778          3            3 3643588562      2999871912       
209        207   19905804
000000017F67D698          3            4 3643588562      2999871912       
209        207   19905804 EM USO
00000001649F3BB0          3            5 3643588562      2999871912       
209        207   19905804

*/

Observem que a mesma query tem o mesmo plano de execução para as três
instâncias, mas para cada instância há vários child number diferentes .
Alguém saberia dizer o que ele significa?

(Ah, se alguém quiser aperfeiçoar a query, esteja a vontade!)



Obrigada,
Lílian Barroso


Responder a