Colega, vc tem ao que parece um problema BEM sério aí, que é gerente
(por definição, um elemento não-técnico, ou que foi um técnico há
muito tempo atrás) querendo ditar normas técnicas, via de regra isso
NUNCA acabe bem... 
 Tecnicamente, é facílimo demonstrar que o seu gerente está
rigorosamente ** ERRADO **, há SIM diferença relativamente apreciável
entre datatype CHAR e NUMBER no bd Oracle, pois CHAR é tamanho fixo e
NUMBER é variável e ainda por cima COMPACTADO, assim NUMBER
necessariamente consome menos espaço, assim na hora dum eventual
RANGE-SCAN obviamente quem é menor demora menos - esse efeito, óbvio,
é reduzidíssimo para keyed-access mas existe, também.. Teste no seu
ambiente e vc verá que não é nada assim do outro mundo, não é o dobro
do tempo, mas que existe, existe. Demonstração :

sys...@test:SQL>CREATE TABLE T (C_CHAR CHAR(36), C_NUM NUMBER)
TABLESPACE USERS NOLOGGING;


sys...@test:SQL>insert into t (select to_char(object_id), object_id
from dba_objects);

sys...@test:SQL>insert into t (select to_char(object_id), object_id
from dba_objects);

sys...@test:SQL>insert into t (select to_char(object_id), object_id
from dba_objects);


sys...@test:SQL>commit;


sys...@test:SQL>create index I_C_CHAR on T(C_CHAR) tablespace users
nologging;


sys...@test:SQL>create index I_C_NUM on T(C_NUM) tablespace users
nologging;


sys...@test:SQL>set timing on
sys...@test:SQL>set autotrace traceonly

==> teste de RANGE SCAN com CHAR :

sys...@test:SQL>select C_CHAR from T where C_CHAR between '0' and
'9999999';

317721 linhas selecionadas.

Decorrido: 00:00:30.29

Plano de Execução
----------------------------------------------------------

------------------------------------------------------------------
| Id  | Operation        | Name     | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1 |    38 |    29   (7)|
|   1 |  INDEX RANGE SCAN| I_C_CHAR |     1 |    38 |    29   (7)|
------------------------------------------------------------------

Estatística
----------------------------------------------------------
         96  recursive calls
          0  db block gets
      23194  consistent gets
       2134  physical reads
          0  redo size
   14044633  bytes sent via SQL*Net to client
     148514  bytes received via SQL*Net from client
      21183  SQL*Net roundtrips to/from client
          3  sorts (memory)
          0  sorts (disk)
     317721  rows processed

sys...@test:SQL>/

317721 linhas selecionadas.

Decorrido: 00:00:23.09

Plano de Execução
----------------------------------------------------------

------------------------------------------------------------------
| Id  | Operation        | Name     | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1 |    38 |    29   (7)|
|   1 |  INDEX RANGE SCAN| I_C_CHAR |     1 |    38 |    29   (7)|
------------------------------------------------------------------


Estatística
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      23175  consistent gets
         26  physical reads
          0  redo size
   14065909  bytes sent via SQL*Net to client
     148514  bytes received via SQL*Net from client
      21183  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     317721  rows processed


==> OK, o melhor tempo ( a segunda execução, de onde pegou blocos no
cache) foi de 23 segundos para ler 317721 linhas, distribuídas em
23175+26=23201 blocos. Já para NUMBER :

sys...@test:SQL>select C_NUM from T where C_NUM between 0 and 99999999;

317721 linhas selecionadas.

Decorrido: 00:00:26.12

Plano de Execução
----------------------------------------------------------

-----------------------------------------------------------------
| Id  | Operation        | Name    | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------
|   0 | SELECT STATEMENT |         |     1 |    13 |    11  (10)|
|   1 |  INDEX RANGE SCAN| I_C_NUM |     1 |    13 |    11  (10)|
-----------------------------------------------------------------


Estatística
----------------------------------------------------------
          1  recursive calls
          0  db block gets
      20101  consistent gets
       1742  physical reads
          0  redo size
    3697964  bytes sent via SQL*Net to client
     129929  bytes received via SQL*Net from client
      18528  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     317721  rows processed

sys...@test:SQL>/

317721 linhas selecionadas.

Decorrido: 00:00:15.39

Plano de Execução
----------------------------------------------------------

-----------------------------------------------------------------
| Id  | Operation        | Name    | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------
|   0 | SELECT STATEMENT |         |   319K|  1869K|   210  (16)|
|   1 |  INDEX RANGE SCAN| I_C_NUM |   319K|  1869K|   210  (16)|
-----------------------------------------------------------------

Estatística
----------------------------------------------------------
          1  recursive calls
          0  db block gets
      21843  consistent gets
          0  physical reads
          0  redo size
    4278647  bytes sent via SQL*Net to client
     148514  bytes received via SQL*Net from client
      21183  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     317721  rows processed

==> 15 segundos para ler as mesmas 317721 linhas, mas em 21843 blocos,
menos tempo porque 21843 é uma qtdade menor do que os 23201 blocos
necessários para armazenar as MESMAS 317721 linhas num índice com
coluna CHAR.... Como eu disse,é meio q óbvio que leva-se MAIS tempo
para ler MAIS blocos... Veja q não é nula nem desprezível a diferença,
a ao mesmo tempo nem é assim enorme, mas que existe, EXISTE, a
afirmação do seu gerente de que CHAR e NUMBER se equivalem só pode ser
FALSA, tecnicamente falando... A documentação para vc se basear é o
documentação Oracle (manuais de Concepts e de Reference), é lá que a
Oracle registra que CHAR ocupam mais espaço que NUMBER, e que NUMBER é
compactado.

 []s

Chiappa

======================================================================
Palestrante ENPO.BR - acesse http://www.enpo- br.org/
Instrutor Workshops ENPO/TWS - acesse http://www.twstecnologia.com.br/
Agora Blogando em www.ora600.com.br - confira as novidades !
======================================================================

'O "Teorema do Ordenado" de Dilbert estabelece que:

"A ignorância é o caminho mais curto para a riqueza"

É possível demonstrá-lo matematicamente a partir dos dois postulados
seguintes com os quais com certeza concorda:

1º Postulado: "O conhecimento é poder"

2º Postulado: "O tempo é dinheiro"

Todos conhecemos o seguinte axioma da Física:

Poder (Potência) = Trabalho/Tempo

Como Conhecimento = Poder

Teremos Conhecimento = Trabalho / Tempo

E como Tempo = Dinheiro

Temos que Conhecimento = Trabalho / Dinheiro

Portanto: Dinheiro = Trabalho / Conhecimento

Assim, se "Conhecimento" se aproxima de zero, "Dinheiro" tende para o 
infinito, independentemente da quantidade de trabalho feito.

Q.E.D.: Quanto menos se sabe mais se ganha'

--- Em oracle_br@yahoogrupos.com.br, "gibajr" <gib...@...> escreveu
>
> Estou trabalhando num projeto onde o Gerente padronizou que todas as 
> tabelas devem ter como chave primária um campo CHAR(36). Tentei 
> argumentar que seria mais interessante um campo number(xxx...).
> Então ele falou que não existe mais diferença no Oracle se o campo é de 
> string ou numérico. Fiquei imaginando uma tabela com 20.000.000 de 
> registros com uma chave primária num campo CHAR(36) (!!!).
> 
> Vocês sabem se existe algum teste de desempenho no datatype do índice 
> ou recomendação da Oracle para utilização do tipo numérico?
>


Responder a