- Este tópico contém 13 respostas, 3 vozes e foi atualizado pela última vez 16 anos, 7 meses atrás por
Rodrigo Almeida.
-
AutorPosts
-
3 de agosto de 2009 às 3:39 pm #88481
eversonpiza
ParticipanteOlá amigos,
Tenho um campo com o seguinte comportamento:
1. Ele nasce com o valor ‘N’
2. É alterado para um número (de 1 a 10), que é o processo que vai trata-lo
3. Depois do tratamento é alterado para ‘S’.Fiz uma pesquisa na internet e a grande recomendação, é usar indice bitmap apenas em campos de pouca alteração, oq não sei se é o meu caso, pois mesmo sendo pouca alteração, elas são feitas muito rapidamente, o fluxo entre inserir com ‘N’ e chegar a ‘S’ pode ser completo em poucos segundos.
Não sei se isso gera muita fragmentação, ou se para uma melhor performance a estatística tem que estar atualizada.Esta é uma tabela com milhões de registros, mas apenas algumas centenas estarão com valores diferentes de ‘S’.
Oq vcs recomendam?
Att.
Everson3 de agosto de 2009 às 3:49 pm #88483Ishii
ParticipanteOlá,
Everson, pergunta: Você vai usar esse campo em muitas pesquisas? Ou melhor esse campo será sempre uma referência ou haverão outros indexadores (PK ou outros…), eu, particularmente, só recomendaria a utilização caso realmente não haja outra maneira e o volume de dados seja alto (centenas de milhões de registros com essa variação binária – S ou N) e não tendo outra opção de consulta.
[]s Ishii
3 de agosto de 2009 às 4:14 pm #88484eversonpiza
ParticipanteOlá Ishii,
Existem sim outros indexadores, mas neste caso eu preciso pegar apenas os registros mais novos da tabela, ou seja, com o processado = ‘N’, e em alguns casos tb pelo número do processo que vai trata-lo, mas muito raramente com processado = ‘S’, não vi outra forma de recuperar estes registros sem ser por este campo.
A ordem de grandeza é +/- assim:
S = dezenas de milhões de registros
N = poucos milhares
= algunas centenas em cada um, que não deve passar de 10.Att.
Everson3 de agosto de 2009 às 4:38 pm #88489Ishii
ParticipanteOlá,
Então nem precisa ser um índice bitmap, a não ser que você faça um
select * from table where coluna = ‘S’
Agora se você colocar mais colunas indexadas na condição e se essa sua estimativa estiver correta, não deve ter um custo alto e acho que a criação de um índice normal somente iria atrapalhar mais…
[]s Ishii
3 de agosto de 2009 às 4:51 pm #88491eversonpiza
ParticipanteA única condição é nesse campo processado.
Acho que vou partir para um índice normal mesmo, concorda?
3 de agosto de 2009 às 5:33 pm #88494Ishii
ParticipanteOlá,
Faça um primeiro teste com o índice normal mesmo. Atualize as estatísticas desta tabela e veja se o índice ajudou ou não…
[]s Ishii
3 de agosto de 2009 às 6:10 pm #88497Rodrigo Almeida
ParticipanteNa verdade o uso do índice BITMAP é para colunas de baixa cardionalidade.
Ou seja, campos que possuem poucos valores distintos. Que é o contrário do B*Tree.
No seu caso, até poderia ser recomendado criar um BITMAP para melhorar a sua pesquisa.
Abraços,
3 de agosto de 2009 às 6:41 pm #88499Ishii
ParticipanteOlá,
Rodrigo, sim eu concordo, porém se o caso da condição usar a menor exceção (milhões de S e milhares de N e alguns de 1-10) você acha que compensaria a criação de um bitmap index se for usar apenas para as exceções?
[]s Ishii
3 de agosto de 2009 às 6:59 pm #88500Rodrigo Almeida
ParticipanteEu acho que vai ter os valores abaixo no campo, me corrija se eu estiver errado:
Valores
===========================
S – N – 1 – 2 – 3 – 4 – 5 – 6 – 7 – 8 – 9 – 10Na teoria, com a cardionalidade é baixa, pois é poucos valores, seria mais performático o Oracle montar um mapa binário desses valores do que criar folhas para o B*Tree.
Porém, possa ser que eu eteja errado. O melhor seria um teste. Mas a sua dúuvida tem sentido Ishii, vejo se faço um teste depois do almoço.
Abraços,
3 de agosto de 2009 às 8:49 pm #88504Rodrigo Almeida
ParticipanteOlá Pessoal,
Bom! Voltei do almoço e efetuei alguns testes, baseando-se nos conceitos dos índices. O teste é bem simples, mas acho que dá para tirar algum aproveito disso.
Veja, vamos criar a tabela e a massa de dados:
SQL> create table TESTE (a number(6), b char(1));Tabela criada.
SQL> declare
2 contador1 integer;
3 contador2 integer;
4 contador3 integer;
5 contador4 integer;
6 contador5 integer;
7 contador6 integer;
8 contador7 integer;
9 contador8 integer;
10 contador9 integer;
11 begin
12 contador1 := 1;
13 contador2 := 10000;
14 contador3 := 20000;
15 contador4 := 30000;
16 contador5 := 40000;
17 contador6 := 50000;
18 contador7 := 60000;
19 contador8 := 70000;
20 contador9 := 80000;
21
22 while contador1 select b, count(b) from teste group by b order by b;B COUNT(B)
N 9999
S 9999
1 9999
2 9999
3 9999
4 9999
5 9999
6 9999
7 99999 linhas selecionadas.
Agora, a criação do índice B*Tree e 2 querys simples.
SQL> create index idx_b_btree on teste (b);═ndice criado.
SQL> select count(b) from teste where b = '2';
COUNT(B)
9999Plano de ExecuþÒo
Plan hash value: 582132316
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 3 | 19 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 3 | | ||* 2 | INDEX RANGE SCAN| IDX_B_BTREE | 11007 | 33021 | 19 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("B"='2')
Note
- 'PLAN_TABLE' is old version
- dynamic sampling used for this statement
EstatÝstica
13 recursive calls 0 db block gets 101 consistent gets 151 physical reads 0 redo size 336 bytes sent via SQL*Net to client 392 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processedSQL> select count(b) from teste where b = '2' and b = '5';
COUNT(B)
0Plano de ExecuþÒo
Plan hash value: 1118252671
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 3 | 0 (0)| |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
|* 2 | FILTER | | | | | ||* 3 | INDEX RANGE SCAN| IDX_B_BTREE | 11007 | 33021 | 19 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter(NULL IS NOT NULL)
3 - access("B"='2')Note
- 'PLAN_TABLE' is old version
- dynamic sampling used for this statement
EstatÝstica
9 recursive calls 0 db block gets 81 consistent gets 0 physical reads 0 redo size 334 bytes sent via SQL*Net to client 392 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processedSQL> drop index idx_b_btree;
═ndice eliminado.
Agora, com o índice BITMAP
SQL> create bitmap index idx_b_bitmap on teste (b);
═ndice criado.
SQL> select count(b) from teste where b = '2';
COUNT(B)
9999Plano de ExecuþÒo
Plan hash value: 4172640382
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
| 2 | BITMAP CONVERSION TO ROWIDS| | 11007 | 33021 | 3 (0)| 00:00:01 ||* 3 | BITMAP INDEX SINGLE VALUE | IDX_B_BITMAP | | | | |
Predicate Information (identified by operation id):
3 - access("B"='2')
Note
- 'PLAN_TABLE' is old version
- dynamic sampling used for this statement
EstatÝstica
44 recursive calls 0 db block gets 85 consistent gets 4 physical reads 0 redo size 336 bytes sent via SQL*Net to client 392 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processedSQL> select count(b) from teste where b = '2' and b = '5';
COUNT(B)
0Plano de ExecuþÒo
Plan hash value: 934706267
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 3 | 0 (0)| |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
|* 2 | FILTER | | | | | |
| 3 | BITMAP CONVERSION TO ROWIDS| | 11007 | 33021 | 3 (0)| 00:00:01 ||* 4 | BITMAP INDEX SINGLE VALUE | IDX_B_BITMAP | | | | |
Predicate Information (identified by operation id):
2 - filter(NULL IS NOT NULL)
4 - access("B"='2')Note
- 'PLAN_TABLE' is old version
- dynamic sampling used for this statement
EstatÝstica
9 recursive calls 0 db block gets 77 consistent gets 0 physical reads 0 redo size 334 bytes sent via SQL*Net to client 392 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processedO índice BITMAP teve um custo de 3 em relação aos 19 do índice B*tree, tornando-se mais eficiente para esse tipo de caso!
Existe um porém também, a tabela é bem simples, usando CHAR como datatype e um volume de dados bem pequeno. Tem que ver se no seu ambiente vai ter a mesma eficiência.
Nem sempre a boa prática é o que prevalece! Esse teste foi mais para matar a curiosidade.
Abraços,
Rodrigo Almeida
[/code]3 de agosto de 2009 às 8:55 pm #88505Ishii
ParticipanteOlá,
Rodrigo, já que estamos testando…e abusando… seria possível ter os seguintes valores:
N: 100
1-10 : 3 de cada
O restante em S.O select considerando o N… acho que isso deve ocorrer no cenário apresentado…
[]s Ishii
4 de agosto de 2009 às 12:08 am #88513Rodrigo Almeida
ParticipanteTESTE!
4 de agosto de 2009 às 12:11 am #88514Rodrigo Almeida
ParticipanteEstá com problemas para publicação do resultado!!!
Acho que o MySQL abriu o bico!! hehehehehehe…
Abraços,
5 de agosto de 2009 às 12:08 am #88552Rodrigo Almeida
Participante
SQL> create table TESTE (a number(6), b char(1));Tabela criada.
SQL> declare
2 contador1 integer;
3 contador2 integer;
4 contador3 integer;
5 contador4 integer;
6 contador5 integer;
7 contador6 integer;
8 contador7 integer;
9 contador8 integer;
10 contador9 integer;
11 begin
12 contador1 := 1;
13 contador2 := 10000;
14 contador3 := 20000;
15 contador4 := 30000;
16 contador5 := 40000;
17 contador6 := 50000;
18 contador7 := 60000;
19 contador8 := 70000;
20 contador9 := 80000;
21
22 while contador1 select b, count(b) from teste group by b order by b;B COUNT(B)
N 9999
S 9999
1 9999
2 9999
3 9999
4 9999
5 9999
6 9999
7 99999 linhas selecionadas.
Agora, a criação do índice B*Tree e 2 querys simples.
Código:
SQL> create index idx_b_btree on teste (b);
═ndice criado.
SQL> select count(b) from teste where b = '2';
COUNT(B)
9999Plano de ExecuþÒo
Plan hash value: 582132316
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 3 | 19 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 3 | | ||* 2 | INDEX RANGE SCAN| IDX_B_BTREE | 11007 | 33021 | 19 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("B"='2')
Note
- 'PLAN_TABLE' is old version
- dynamic sampling used for this statement
EstatÝstica
13 recursive calls 0 db block gets 101 consistent gets 151 physical reads 0 redo size 336 bytes sent via SQL*Net to client 392 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processedSQL> select count(b) from teste where b = '2' and b = '5';
COUNT(B)
0Plano de ExecuþÒo
Plan hash value: 1118252671
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 3 | 0 (0)| |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
|* 2 | FILTER | | | | | ||* 3 | INDEX RANGE SCAN| IDX_B_BTREE | 11007 | 33021 | 19 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter(NULL IS NOT NULL)
3 - access("B"='2')Note
- 'PLAN_TABLE' is old version
- dynamic sampling used for this statement
EstatÝstica
9 recursive calls 0 db block gets 81 consistent gets 0 physical reads 0 redo size 334 bytes sent via SQL*Net to client 392 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processedSQL> drop index idx_b_btree;
═ndice eliminado.
-
AutorPosts
- Você deve fazer login para responder a este tópico.