Hay una serie de índices aparte de los convencionales, que son poco conocidos, pero no por ello dejan de ser muy útiles.
GIN - índices optimizados para la búsqueda de subelementos, dentro de una columna, por ejemplo columnas de tipo Array, columnas que almacenen JSON o campos de texto para hacer búsquedas FTS (Full Text Search).
GIST - índices para búsquedas de datos geolocalizados.
BRIN - índices que ahorra espacio de almacenamiento para aquellos datos que se encuentran ordenados de forma natural. Por ejemplo las entradas de un fichero log, siempre se generan de forma secuencial en base al campo de fecha de la entrada.
HASH - indice optimizado en velocidad para la búsqueda de elementos por igualdad. Por ejemplo la dirección de email de usuarios. Usando este índice tendríamos máxima velocidad de acceso para buscar a un usuario por su email.
Intentando arrojar un poco de luz a problemas que puedes encontrarte. Especialmente con PostgreSql
Mostrando entradas con la etiqueta tuning. Mostrar todas las entradas
Mostrando entradas con la etiqueta tuning. Mostrar todas las entradas
lunes, 28 de mayo de 2018
jueves, 19 de febrero de 2015
analizando consultas en Postgresql. Parte I
Tenemos una potente herramienta para analizar las consultas en PostgreSQL: explain analyze
explain analyze select * from usuario; Seq Scan on usuario (cost=0.00..4743.71 rows=44471 width=243) (actual time=0.026..59.431 rows=44474 loops=1) Total runtime: 63.645 ms (2 filas)
Seq Scan, significa que la consulta se hará fila a fila secuencialmente sin acceso por índice.
El valor numérico cost=0,00, es el tiempo que tiene que esperar la consulta en ser ejecutada. En este caso el tiempo es 0.00 porque puede ejecutarse inmediatamente.
El segundo valor 4743,71, es el numero de fetches necesarios para recuperar todas las filas de la consulta, el número de fetches lo podemos minimizar por ejemplo aplicando LIMIT.
Rows=44.471 es el número de filas que devolverá la consulta y width el tamaño medio en bytes de cada fila.
Truco: si vas a realizar análisis de operaciones de escritura, encierralas en un bloque de transacción, para poder ejecutarlas las veces que necesites y que no se produzcan cambios en la base de datos:
begin; explain analyze insert ...; rollback;
Etiquetas:
optimización,
postgres,
postgresql,
tuning
jueves, 26 de septiembre de 2013
Indices no utilizados en postgresql
Consultar los índices de tu bbdd que no están siendo utilizados, para ahorrar espacio o replantearte sus campos:
SELECT
schemaname || '.' || relname AS table,
indexrelname AS index,
pg_size_pretty(pg_relation_size(i.indexrelid)) AS index_size,
idx_scan as index_scans
FROM pg_stat_user_indexes ui
JOIN pg_index i ON ui.indexrelid = i.indexrelid
WHERE NOT indisunique AND idx_scan < 50 AND pg_relation_size(relid) > 5 * 8192
ORDER BY pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST,
pg_relation_size(i.indexrelid) DESC;
Etiquetas:
optimización,
postgres,
postgresql,
tuning
lunes, 3 de septiembre de 2012
Estadísticas de acierto de la cache
Es muy interesante saber en nuestra base de datos cuantas veces encontramos en la caché el resultado de las consultas. Si tenemos valores altos, seguro que no accedemos al disco a buscar los resultados y por lo tanto nuestra base de datos está funcionando bien.
Vamos a ver el porcentaje de acierto a nivel de base de datos:
SELECT d.datname, pg_database_size(d.datname), SUM(pg_stat_get_db_blocks_hit(d.oid)) / SUM(pg_stat_get_db_blocks_fetched(d.oid)) AS hit_rate
FROM pg_database d
GROUP BY d.datname
HAVING SUM(pg_stat_get_db_blocks_fetched(d.oid)) > 0
Pero aún más interesante es ver el resultado a nivel de tabla:
select t.schemaname, t.relname, heap_blks_hit*100/(heap_blks_hit+heap_blks_read) as BCHR
from pg_statio_user_tables t
where t.heap_blks_read > 0
Si tus tablas más accedidas tienen valores superiores a 95% todo va bien.
Sino revisa tus valores de "shared_buffers" y "effective_cache_size", si son correctos quizá tengas que revisar tus sentencias o aumentar tu memoria.
Referencias:
http://blog.kimiensoftware.com/2011/05/postgresql-vs-oracle-differences-4-shared-memory-usage-257
Vamos a ver el porcentaje de acierto a nivel de base de datos:
SELECT d.datname, pg_database_size(d.datname), SUM(pg_stat_get_db_blocks_hit(d.oid)) / SUM(pg_stat_get_db_blocks_fetched(d.oid)) AS hit_rate
FROM pg_database d
GROUP BY d.datname
HAVING SUM(pg_stat_get_db_blocks_fetched(d.oid)) > 0
Pero aún más interesante es ver el resultado a nivel de tabla:
select t.schemaname, t.relname, heap_blks_hit*100/(heap_blks_hit+heap_blks_read) as BCHR
from pg_statio_user_tables t
where t.heap_blks_read > 0
Si tus tablas más accedidas tienen valores superiores a 95% todo va bien.
Sino revisa tus valores de "shared_buffers" y "effective_cache_size", si son correctos quizá tengas que revisar tus sentencias o aumentar tu memoria.
Referencias:
http://blog.kimiensoftware.com/2011/05/postgresql-vs-oracle-differences-4-shared-memory-usage-257
jueves, 30 de agosto de 2012
Indices OnlyScan
A partir de Postgres 9.2 tenemos índices que si contienen los campos necesarios de una consulta, no acuden a la tabla a recuperar la información, sino que la recuperan directamente del índice. Para disfrutar de esta mejora tenemos que activar la consulta de este modo: SET enable_indexonlyscan TO true;Podeis ver ejemplos de uso en: http://michael.otacoo.com/postgresql-2/postgresql-9-2-highlight-index-only-scans/ Tened cuidado al utilizarlo para no crear índices sobre campos que se actualicen muy a menudo, ya que perderemos rendimiento durante las actualizaciones e inserciones y no compensará la ganancia sobre las consultas.
miércoles, 22 de agosto de 2012
Creación de índices
Cuando en producción nos encontramos que tenemos que optimizar las consultas, nos encontraremos a veces que no podemos parar los servidores.
La optimización muchas veces pasa por crear un índice para alguna tabla, pero en Postgres esta operación bloquea la tabla.
Esto puede hacer caer el servidor de aplicaciones en el caso de aplicaciones web dinámicas, si el índice es muy grande.
Por fortuna Postgres nos facilita hacer esta operación de forma concurrente sin necesidad de bloquear la tabla, la operación será más lenta pero podremos hacerla en caliente:
CREATE INDEX CONCURRENTLY idx_salary ON employees(last_name, salary);
La optimización muchas veces pasa por crear un índice para alguna tabla, pero en Postgres esta operación bloquea la tabla.
Esto puede hacer caer el servidor de aplicaciones en el caso de aplicaciones web dinámicas, si el índice es muy grande.
Por fortuna Postgres nos facilita hacer esta operación de forma concurrente sin necesidad de bloquear la tabla, la operación será más lenta pero podremos hacerla en caliente:
CREATE INDEX CONCURRENTLY idx_salary ON employees(last_name, salary);
Suscribirse a:
Entradas (Atom)