RE: tipo de datos

From: "Fernando Hevia" <fhevia(at)ip-tel(dot)com(dot)ar>
To: "'Agustin Ignacio Genoves'" <agustingenoves(at)gmail(dot)com>
Cc: "'POSTGRES'" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: RE: tipo de datos
Date: 2010-06-18 15:07:15
Message-ID: 244A6DC64E244881AF3D5745DF37F484@iptel.com.ar
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

> -----Mensaje original-----
> De: Agustin Ignacio Genoves [mailto:agustingenoves(at)gmail(dot)com]
>
> Ok, gracias, lei el manual varias veces, lo que yo preguntaba
> es si alguien habia experimentado diferencias mas alla de la teoria.
> Necesitaba saber si (aunque es obvio que muchos definimos
> columnas con character varying(n) o character(n)) alguien
> habia experimentado a nivel tiempos de respuesta, indices,
> espacios, osea algo mas empirico en distintos ambientes, por
> ahi fui escueto al plantearlo, pero lo hago ahora. ¿Alguien
> ha hecho pruebas de performance para apoyar o no las posibles
> diferencias? Nosotros tenemos diferencias de performance a
> nivel indices y estamos probando para ver si estamos haciendo
> lo correcto o hay algo mas. Cualquier dato que puedan pensar
> que modifique la performance a nivel indices sobre columnas
> varchar(n) (hemos realizado vacuum, revisado la conf del
> server, probamos varias formas de consulta) seria de gran
> ayuda. Se que faltan mas detalles, pero quisiera eliminar la
> posibilidad de que este tipo de datos con indices traiga
> problemas, en lo personal no lo creo. Lo que si detectamos es
> que si una tabla tiene char(42) y otra tabla tiene
> varchar(42) y ambas indices por esos campos (y datos de esas
> longitudes) cuando hacemos un join dichas consultas no usan indices.
> Muchas Gracias
>

Acabo de probarlo y el tipo de dato text es el más rápido. Las pruebas
fueron hechas sin rigor científico por lo que te paso abajo un rápido
ejemplo de como hice las pruebas por si querés elaborar a partir de allí.
Básicamente son 3 tablas con los 3 tipos de datos: char, varchar y text.
Inserto 1M de registros, los indexo y luego busco 100.001 registros por
índice.

Cada búsqueda fue repetida unas 3 ó 4 veces para cada tipo de dato pero puse
un único resultado de cada uno ya que fueron todos muy similares, con no más
de 2 milisegundos de diferencia entre si.
Fueron hechas bajo Postgres 8.4.4 y el kernel 2.6.24-24-server #1 x86_64
GNU/Linux.

La conclusión:

* Insertar 1 millón de registros:
char 4515.685 ms
varchar 4128.320 ms
text 3922.586 ms

Estos tiempos posiblemente muestren la incidencia en ciclos de cpu para
validar que se cumpla la longitud máxima de los tipos de datos char y
varchar. Repetí 2 veces los inserts y los tiempos se mantuvieron.

* Crear un índice sobre 1 millón de registros:
char 3026.122 ms
varchar 2801.183 ms
text 2804.505 ms

varchar y text son ~7% más rápidos.

* Buscar 100.001 registros en un millón:
char 869.5 ms (~8.3% más lento)
varchar 821.0 ms (~2.5% más lento)
text 802.9 ms

Los tiempos pareciera que los ciclos de cpu para validar que se cumpla la
longitud máxima inciden en mayor proporción, más si consideramos que la
lectura se hace en bloques

create table prueba_c( campo char(32) );
create table prueba_v( campo varchar(32) );
create table prueba_t( campo text );

# insert into prueba_c ( campo)
select md5(generate_series(1, 1000000)::text);
INSERT 0 1000000
Time: 4515.685 ms

# insert into prueba_v ( campo)
select md5(generate_series(1, 1000000)::text);
INSERT 0 1000000
Time: 4128.320 ms

# insert into prueba_t ( campo)
select md5(generate_series(1, 1000000)::text);
INSERT 0 1000000
Time: 3922.586 ms

# alter table prueba_c add constraint prueba_c_pk primary key (campo);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index
"prueba_c_pk" for table "prueba_c"
ALTER TABLE
Time: 2995.634 ms

# alter table prueba_t add constraint prueba_t_pk primary key (campo);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index
"prueba_t_pk" for table "prueba_t"
ALTER TABLE
Time: 2916.229 ms

# alter table prueba_v add constraint prueba_v_pk primary key (campo);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index
"prueba_v_pk" for table "prueba_v"
ALTER TABLE
Time: 2906.322 ms

# select count(*) from prueba_c join (select md5(generate_series(200000,
300000)::text)::char(32) as clave) a on (campo = clave);
count
--------
100001
(1 row)

Time: 869.521 ms

# select count(*) from prueba_v join (select md5(generate_series(200000,
300000)::text)::varchar(32) as clave) a on (campo = clave);
count
--------
100001
(1 row)

Time: 812.011 ms

# select count(*) from prueba_t join (select md5(generate_series(200000,
300000)::text)::text as clave) a on (campo = clave);
count
--------
100001
(1 row)

Time: 802.949 ms

Saludos,
Fernando.

Pd: efectivamente, para entrar por índice siempre deben coincidir los tipos
de datos. Lo resolvés con casts. De todas maneras si se te presenta esa
situación es porque tenés errores en el modelo de datos.

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Agustin Ignacio Genoves 2010-06-18 15:26:44 Re: tipo de datos
Previous Message Agustin Ignacio Genoves 2010-06-18 11:30:05 Re: tipo de datos