(esta respuesta es un Wiki, puedes editar - ¡por favor, corrige y mejora!)
ACTUALIZACIÓN DE BENCHMARKS PARA 2016 (página 9.5+)
Y utilizando benchmarks "pure SQL" (sin ningún script externo)
-
utilizar cualquier generador de cadenas con UTF8
-
principales benchmarks:
2.1. INSERTAR
2.2. SELECCIONAR comparando y contando
CREATE FUNCTION string_generator(int DEFAULT 20,int DEFAULT 10) RETURNS text AS $f$
SELECT array_to_string( array_agg(
substring(md5(random()::text),1,$1)||chr( 9824 + (random()*10)::int )
), ' ' ) as s
FROM generate_series(1, $2) i(x);
$f$ LANGUAGE SQL IMMUTABLE;
Preparar prueba específica (ejemplos)
DROP TABLE IF EXISTS test;
-- CREATE TABLE test ( f varchar(500));
-- CREATE TABLE test ( f text);
CREATE TABLE test ( f text CHECK(char_length(f)<=500) );
Realizar una prueba básica:
INSERT INTO test
SELECT string_generator(20+(random()*(i%11))::int)
FROM generate_series(1, 99000) t(i);
Y otras pruebas,
CREATE INDEX q on test (f);
SELECT count(*) FROM (
SELECT substring(f,1,1) || f FROM test WHERE f<'a0' ORDER BY 1 LIMIT 80000
) t;
... Y utilizar EXPLAIN ANALYZE
.
ACTUALIZADO NUEVAMENTE 2018 (página 10)
pequeña edición para agregar los resultados de 2018 y reforzar recomendaciones.
Resultados en 2016 y 2018
Mis resultados, después de promediar, en muchas máquinas y muchas pruebas: todos iguales
(estadísticamente menos que la desviación estándar).
Recomendación
-
Usar el tipo de dato text
,
evitar el antiguo varchar(x)
porque a veces no es estándar, por ejemplo en cláusulas de CREATE FUNCTION
varchar(x)
≠varchar(y)
.
-
expresar límites (¡con el mismo rendimiento de varchar
!) con la cláusula CHECK
en el CREATE TABLE
por ejemplo CHECK(char_length(x)<=10)
.
Con una pérdida de rendimiento negligible en INSERT/UPDATE también puede controlar rangos y estructura de cadena
por ejemplo CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')