[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