[firebase-br] Collate e Character Set

Edson T. Marques marques em oriontec.com.br
Qua Jan 19 11:45:23 -03 2005


Aproveitando a deixa eu gostaria de relatar algumas esperiências que fiz 
e, se for possível, comentários seriam bem vindos.

Configurações:
Servidor Linux SuSE 9.1 completamente "patched"
Firebird: FirebirdSS-1.5.1.4481-0.i686-PTBR-nptl.tar.gz ((Valeu pessoal 
da PHA!!))
Cliente: Terminal Linux Suse, acessando Servidor Win2003 via "Terminal 
Server" (RDesktop)
Programa (Cliente): IBExpert Versao 2004.10.30

Obs.:
  1) O Banco de dados foi gerado com characterset Win1252.
  2) O Banco de Dados Possui um conjunto de tabelas para estruturar os 
endereços das pessoas:
  Tabelas: Pessoas, EndPessoas, Enderecos (Rua, Numero, Complemento), 
CEP, Bairros, Localidades, Municipios (Nome), UF (Sigla, Nome) e Pais 
(Nome).
  3) Os dados podem ser inseridos sem preocupação com CAIXA dos caracteres.
  4) Existem em vários países cadastrados, a chave primária é o campo NOME.
  5) Existe um País cadastrado com o NOME : "Alemanha".

Teste: de consultas:

1) select * from PAIS where NOME = 'ALEMANHA'
    Resultado: Retornou tudo null. (não encontrou o registro)

2) select * from PAIS where NOME = 'Alemanha'
  Resultado: Retornou o registro referente a Alemanha e estabeleceu 
automaticamente o seguinte PLAN:
  PLAN: (PAIS INDEX (RDB$PRIMARY92)) (que corresponde à "primary key")

3) select * from PAIS where NOME = 'Alemanha' plan (PAIS index 
(RDB$PRIMARY92))
  Resultado: O mesmo anterior. (usando p PLAN informado)

4) select * from PAIS where Upper(NOME) = 'ALEMANHA'
  Resultado: Retornou o registro referente a Alemanha e estabeleceu 
automaticamente o seguinte PLAN:
  PLAN: (PAIS NATURAL)

5) select * from PAIS where NOME collate WIN_PTBR = 'ALEMANHA'
  Resultado: Retornou o registro referente a Alemanha e estabeleceu 
automaticamente o seguinte PLAN:
  PLAN: (PAIS NATURAL)

6) select * from PAIS where Upper(NOME) = 'ALEMANHA' plan (PAIS index 
(RDB$PRIMARY92))
  Resultado: Erro na consulta: "o PLAN não pode ser usado para essa 
consulta"
 
7) select * from PAIS where NOME collate WIN_PTBR = 'ALEMANHA' plan 
(PAIS index (RDB$PRIMARY92))
  Resultado: Erro na consulta: "o PLAN não pode ser usado para essa 
consulta"

Conclusões:
a) A consulta 1 não tem retorno por razões óbvias.
b) A consulta 2 tem seu retorno e dá certo também por razões óbvias. 
Provavelmente é o que a grande maioria dos programadores normalmente usa 
("lei do menor esforço, com bom senso, é claro").
c) A consulta 3 é a mais eficiente de todas não dá trabalho nenhum (em 
termos) para o BD a não ser o de fazer diretamente a consulta sem ter 
que calcular o melhor caminho para isso (PLAN).
d) A consulta 4 tem uma eficiência bem reduzida (se comparada com a 
anterior) porque usa a função UPPER. Não é possível usar um índice 
existente para aumentar a performance da consulta. Mesmo assim existe o 
trabalho de tentar calcular o PLAN.
e) Até aqui não tinha surpresa. Eu já imaginava que seria dessa maneira. 
Minhas suposições tiveram que mudar a partir da consulta 5 onde eu 
esperava que o FB conseguisse usar o indice da PK para aumentar a 
performance. Não sei porque eu supunha isso, mas vejo na prática que 
isso não acontece. Será que isso tem solução?
f) As duas últimas consultas me deixaram extremamente frustrado pois 
concluí que as suposições que eu fazia sobre este aspecto do FB são 
completamente equivocadas.

Considerações finais:
Pelo que vejo não há como melhorar a performance dessas consultas e 
assim fica complicado implementar a estrutura que desejo no meu BD. Eu 
tenho que fazer várias operações nos triggers para tirar do usuário o 
trabalho de entrar diretamente com esses dados em interfaces distintas. 
É que meu sistema possui um cadastro de Pessoas onde alguns campos como 
os de Endereço Principal (residencia ou sede), Endereço de Entrega, do 
Trabalho e de Cobrança, são editados diretamente pelo usuário, ao mesmo 
tempo (na mesma interface) que ele preenche os demais dados da Pessoa 
que está sendo Cadastrada, Alterada ou Deletada. Dessa forma eu faço 
tudo por baixo dos panos, distribuindo ou deletando esses dados nas 
respectivas tabelas usando triggers. Bom, daí que para isso eu 
fatalmente terei que fazer diversas pequenas consultas para saber se um 
País, um Estado, um Município etc já estão cadastrados, ou se ainda são 
usados, o que vai fazer de tudo isso um processo relativamente bem 
Pesado, quando comparamos com a situação de que todos os registros 
poderiam estar em uma única e grande tabela.

Grato pela atenção.

Edson T. Marques
Oriontec - Orion Sistemas
Viçosa-MG




Mais detalhes sobre a lista de discussão lista