[Pgsql-ayuda] Problema con funciones

Alvaro Herrera alvherre@dcc.uchile.cl
Fri, 20 Jun 2003 14:56:37 -0400


On Fri, Jun 20, 2003 at 08:09:32PM +0200, Antonio Castro wrote:
> On Fri, 20 Jun 2003, Alvaro Herrera Munoz wrote:
> 
> > On Fri, Jun 20, 2003 at 08:05:11AM +0200, Antonio Castro wrote:
> > > Me da la impresi?n que esto afecta al rendimiento de los indices
> > > sobre campos de tipo char(n).
> > 
> > Pura especulacion, o hiciste mediciones?
> 
> Si es pura especulación. Para hacer una pruebecita rápida y mal prefiero
> no hacerla.

Yes.  Yo tampoco he hecho ninguna prueba.

> De todas formas según los casos la diferencia de tamaño de los campos
> indexados puede ser superior al doble. Sospecho que almenos en algún
> caso si pueda representar un menor rendimiento. Es solo sentido común
> pero no puedo afirmarlo categoricamente.

El asunto es que creo que Unicode (o al menos UTF-8) deja en 1 byte
todos los simbolos de iso-8859-15, y el resto en un largo variable de
bytes.  En este sentido los strings que quepan dentro de iso-8859-15
usan el mismo espacio (mono-byte) en UTF-8 que en otras codificaciones.

> > Unicode no es la unica codificacion multibyte.
> 
> Bueno las otras codificaciones multibyte tendrán el mismo problema.

Ciertamente.

> > Si quieres usar una codificacion mono-byte pero poder usar "legalmente"
> > valores no ASCII (acentos, etc), usa una codificacion iso-8859-1 o
> > iso-8859-15.  Usar SQL_ASCII es buscarse problemas en general.
> 
> Y si quiero usar codificacion mono-byte para un campo y usar 
> Unicode en otros campos me tendré que fastidiar claro.

Bueno, efectivamente es asi :-(  Esta pendiente implementar la capacidad
de definir codificacion campo por campo.  O era definir un locale campo
por campo?  Hey, este asunto de codificar caracteres y asegurar que por
ejemplo el ordenamiento de strings se hace correctamente en los
distintos locales y para distintas codificaciones es bastante complejo.

> > Por eso recomiendo usar "char" con las comillas para almacenar un solo
> > caracter.  Eso te limita a no usar cosas multibyte y no lleva los 4
> > bytes de largo al principio.
> 
> Pues precisamente el uso de "char" con comillas pone de manifiesto
> una cosa. Un sistema de codificación no tiene porque afectar 
> necesariamente a todos los tipos que se basan en el uso de caracteres.

No deberia, pero en la practica es asi.

> En Postgres por desgracia la codificación afecta a text, char(n), 
> varchar(n), y no se cuantas cosas más. No había necesidad de afectar
> al tipo char(n). Yo creo que al usar codificacion multibyte tanto
> para char(n), como para varchar(n) estamos desperdiciando la posibilidad
> de respetar el tipo char(n) para campos de longitud fija. Yo creo que
> el uso de char(n) y varchar(n) se convierte en la misma cosa cuando se
> usa codificación multibyte. Si yo quiero usar un campo para codificar
> artículos con cuatro caracteres los acentos y la eñes me sobran. 

Lo que sucede es que el estandar dice que char(n) debe limitar el string
a n _caracteres_, no n bytes.  Si un caracter usa mas de un byte, como
vas a representar esa informacion?  El campo es de longitud fija para el
humano, pero la maquina puede necesitar longitud variable.

> Si se hubiera dejado al marjen el tipo char(n) se podría elegir entre
> char(n) y varchar(n) para cosas distintas. Es decir si alguien quiere 
> usar acentos y eñes podría recurrir a varchar(n) y si no quiere
> usar acentos y le conviene codificar de manera eficiente unos indices de
> tamaño fijo con cuatro caracteres podría usar el tipo char(4). 

Bueno, si quieres guardar cuatro bytes puedes usar int.  Eso es lo mas
eficiente... sobre todo porque la operatoria de punto fijo es super
eficiente en hardware, y eso ayuda mucho al momento de usar indices.
Para acceder a cada byte, usas << (desplazamiento de bits).

> Quizás exista algo tipo "char (n)" entre comillas o similar y yo no
> lo conozco.

No, no existe.

> "char" está muy bien pero para campos de un solo byte.

Obvio, no sirve para otra cosa.

De todas maneras, hace algun tiempo Manfred Koizar publicó en
pgsql-general un tipo especifico para columnas de largo fijo, con
bastante ganancia de rendimiento.  Puede servirte si lo necesitas para
algo.  El mensaje de anuncio esta aqui:

http://archives.postgresql.org/pgsql-performance/2002-10/msg00089.php

-- 
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Linux transformó mi computadora, de una `máquina para hacer cosas',
en un aparato realmente entretenido, sobre el cual cada día aprendo
algo nuevo" (Jaime Salinas)