Vous êtes sur la page 1sur 18

2013

Microsoft Josu Vinicio Alemn Watters

[Algunos consejos generales para aumentar el rendimiento en PostgreSQL]


Tres importantes investigaciones acerca de cmo sacarle el jugo a este manejador de BD.

Primera Investigacin

Tuning al rendimiento de PostgreSQL


Publicado el 9 septiembre, 2011 por wiccano Publicado en Sin categora 2 respuestas

Antes en entrar en el tema me parece importante aclarar el trmino anglosajn Tuning con el que nos referimos a puesta a punto de algo. PostgreSQL es actualmente la Base de Datos SQL de cdigo abierto ms avanzada y flexible. Con este poder y flexibilidad enfrentamos un problema: los desarrolladores de PostgreSQL suelen ajustar la configuracin de modo general, lamentablemente esto no se debe hacer. Esto se hace para asegurar que el servidor arrancar casi con cualquier configuracin hardware. El punto esta en que cada base de datos no solo es diferente en su diseo sino tambin en sus necesidades. Algunas por ejemplo, se usan para recopilar grandes cantidades de datos que casi nunca son consultados y otras en cambio tienen datos estticos y que son consultados frecuentemente. Sin embargo la mayora de sistemas tienen niveles de escritura y lectura sobre la base de datos, generalmente desiguales. Sumando a esto la estructura total de la base de datos, sus tipos de datos y configuracin de hardware hacen que hacer tuning al rendimiento de PostgreSQL no sea una tarea fcil. Sitios de Referencia: http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server Entendiendo el proceso El primer paso para entender como funciona una base de datos PostgreSQL es entender el ciclo de vida de una consulta. Estos son los pasos que sigue una consulta:
1. 2. 3. 4. 5. Transmisin de la cadena de consulta al backend de la base de datos Anlisis(Parsing) de la cadena de consulta Planificacin de la consulta para optimizar la recuperacin de datos Recuperacin de datos desde el hardware Transmisin de los resultados del cliente

El primer paso es el envo de la cadena de consulta (el comando SQL que se tipea desde la aplicacin que se este usando) a la base de datos. No hay mucho que usted pueda ajustar en este punto. Sin embargo si usted tiene consultas muy grandes o largas que no se construyen de forma avanzada puede optar por ponerlas en la base de datos como procedimientos

almacenados y as cortar la transferencia de datos a un mnimo que vendra siendo el llamado al procedimiento almacenado. Una vez que la consulta SQL esta dentro del servidor de base de datos es analizada(Parsed). Este paso tambin puede evitarse con algunas consultas creando procedimientos almacenados. En la planificacin de la consulta es donde PostgreSQL realmente comienza a hacer algn trabajo. Esta etapa de controles verifican si la consulta ya esta preparada, si la versin de PostgreSQL y librerias cliente soportan esta caracterstica, funcin o consulta. Se analiza tambin el SQL para determinar cual es la forma ms eficiente para recuperar los datos. Se podra usar un Index, si es as cual debe ser?. Quizs un hashjoin en las dos tablas es lo adecuado?. Estas son algunas de las decisiones que la base de datos toma en este punto del proceso. Este paso puede ser eliminado si la consulta es previamente preparada. Ahora que PostgreSQL tiene un plan de lo que cree, es la mejor manera de recuperar los datos, es hora de hacerlo realidad. Si bien hay algunas opciones de optimizacin en este punto del proceso, la mayora de son realizadas por la configuracin de hardware. Y finalmente el ltimo paso es transmitir los resultados al cliente. Si bien no hay opciones de optimizacin real en este paso es importante tener en cuenta que todos los datos que se van a devolver son tomados desde el disco y son enviados a travs de los medios de conexin al cliente. Minimizar el nmero de filas y columnas a solo aquellas que son necesarias a menudo puede incrementar el rendimiento. Cuando inicializamos la base de datos PostgreSQL define unos valores por defecto, estos valores son muy bajos teniendo en cuenta el hardware moderno y de entrada es lo primero que se debe revisar en el momento de realizar Tuning al rendimiento del motor. La estratgia de como se debe realizar depende de la magnitud y complejidad la o las bases de datos. La informacin de Hardware es lo primero que debe obtener y as saber con que recursos disponemos. Luego revisamos que tipo de sistemas tenemos, que predomina, la consulta? la escritura?, existen procesos complejos de procesamiento? que recursos va a utilizar Apache y PHP y cuales PostgreSQL?, que cantidad de conexiones se producen simultaneamente, etc Esta informacin obetenida sumada a la configuracin actual de la mquina y a los resultados de desempeo que actualmente se tienen de la base de datos y del sistema en general nos da un punto de partida para realizar el tuning al rendimiento de postgresql. Tomando las medidas de contingecia respectivas, todo es un juego de tire y afloje. Aumente los valores de configuracin o disminuyalos, inclusive llegando a degradar el sistema y as fijar los limites de rendimiento que podemos llegar a tener. A continuacin describo las principales opciones de configuracin

de PostgreSQL que unas ves comprendidas permiten realizar movimientos lgicos de configuracin en buscan de configuraciones acertadas para un sistema en particular.

Archivo de Configuracin postgresql.conf Siempre que realice cambios sobre este archivo debe reiniciar PostgreSQL En otro capitulo se describen detalladamente las principales opciones de este archivo de configuracin. Por ahora nos vamos a centrar en 3 parametros de configuracin El nmero de shared_buffers es el parmetro que ms afecta al rendimiento de PostgreSQL. Este valor, de tipo entero, indica el nmero de bloques de memoria o buffers de 8KB (8192 bytes) que postgres reservar, como zona de trabajo, en el momento del arranque para procesar las consultas. De forma predeterminada (enpostgresql.conf), su valor es de 1000. Un nmero claramente insuficiente para conseguir un rendimiento mnimamente aceptable. Estos buffers se ubican dentro de los denominados segmentos de memoria compartida. Es importante saber que el espacio ocupado por el nmero de buffers que pretendamos asignar, nunca podr exceder al tamao mximo que tengan los segmentos de memoria. En caso contrario, postgres se negar a arrancar avisando con un error que no puede reservar el espacio solicitado. Ahora de forma prctica, vamos a suponer que tenemos un server con 8GB en RAM y vamos a iniciar dejando 3GB como espacio reservado para postgres. 8GB = 8256992 (esta equivalencia solo la tomo de los datos reportados por el OS) 4GB = 8256992 / 2 = 4128496K
shared_buffers: (4128496 KB/8 KB) = 516062

Es posible que al fijar este valor a shared_buffers en el archivo postgresql.con f nos genere un error de este tipo

FATAL: DETALLE: 03600). HINT:

no se pudo crear el segmento de memoria compartida: Argumento invlido La llamada a sistema fallida fue shmget(key=5432001, size=112009216,

Este error generalmente significa que una peticin de PostgreSQL para

obtener un segmento de memoria compartida excedi el parmetro SHMMAX del kernel. Puede reducir el tamao de la peticin o reconfigurar el kernel con Para reducir el tamao de la peticin (actualmente

un SHMMAX superior.

112009216 bytes), reduzca el parmetro de PostgreSQL shared_buffers (actualmente 13107) y/o el parmetro max_connections (actualmente 100). Si el tamao de la peticin ya es pequeo, es posible que sea inferior al parmetro SHMMIN del kernel, en cuyo caso se requiere alzar el tamao de la peticin o disminuir SHMMIN. La documentacin de PostgreSQL contiene ms informacin acerca de la configuracin de memoria compartida.

Nota: recuerda que este valor no debe ser fijado como formula, sino que puede se r un punto de partida. Recuerda que muchas veces hay que fijar valores tan altos (con conocimiento de causa claro esta) que hagan que el sistema no funcione ms, as encontrars los lmites de t configuracin.

El tamao ocupado por los 516062 buffers que has pedido reservar, simplemente no caben en el tamao actual de segmento (SHMMAX). Postgres en el arranque intenta reservar este espacio pero el sistema operativo no se lo permite. En Linux, de forma predeterminada, el tamao de un segmento de memoria compartida es de 32MB. Podemos comprobarlo haciendo (el resultado es en n de bytes): shell> cat /proc/sys/kernel/shmmax 33554432 Y el espacio que requiere el nmero de buffers, es superior al tamao del segmento:
516062 buffers ocupan 4227579904 (516062 * 8192 bytes/bloque) > 33554432

La solucin est en modificar el tamao mximo del segmento de memoria compartid a. Esto lo hacemos asignando un nuevo valor al parmetro del kernel SHMMAX

shell> sysctl -w kernel.shmmax=4227579904 Ahora, para fijar shmall debes ver como lo fija el mismo OS al momento de cargar, esto lo puedes ver en /usr/include/linux/shm.h. Encontrars algo como esto:

#define SHMMAX 02000000 #define SHMMIN 1 #define SHMMNI 4096 #define SHMSEG SHMMNI Luego podemos decir que:

/* max shared seg size (bytes) */ /* min shared seg size (bytes) */ /* max num of segs system wide */ /* max shared segs per process */

#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))

shmall = 4227579904 / 4096 * (4096 / 16) = 264223744 // estamos hablando de cerca de 260MB frente a los 4GB de shmmax shell> sysctl -w kernel.shmall=264223744 Ahora debes guardar este valor de forma permanente en /etc/sysctl.conf, de forma que los cambios se conserven entre arranques: kernel.shmmax=4227579904 kernel.shmall=264223744 Podemos confirmar de esta forma, aunque en este punto los valores ya deben estar cargados.
sysctl -p /etc/sysctl.conf

Si necesitas ms detalles de la configuracin de los parametros del kernel puedes revisar la documentacin oficial aqu
######################################################################

La primer seccin de este archivo es FILE LOCATIONS, es fcil de interpretar, no voy a entrar en detalles. La segunda seccin es CONNECTIONS AND AUTHENTICATION. Esta seccin de conexiones se encuentra subdividida en 4 partes: tipo de conexiones, parmetros de autenticacin, kerberos y TCP. En su configuracin inicial, Postgres solo puede ser accedido desde socket unix, sin puertos TCP/IP abiertos. Conexiones listen_addresses = localhost Listado separado por comas de los host desde los cuales se aceptarn conexiones. De estar comentado ocon valor *, acepta desde cualquier host. port = 5432 Puerto en el cual esta escuchando esta instancia de Postgres. Notar que con esta directiva se puedenejecutar mltiples instancias del DBMS.

max_connections = 100 Cantidad mxima de conexiones permitidas(backends) en un mismo tiempo, sin considerar al superusuario. Aumentar este parmetro conlleva un mayor uso de memoria compartida. Al cambiar este parmetro tenga en cuenta que otros parmetros como work_men se configura con relacin a cada cliente. superuser_reserved_connections = 2 Cantidad de slots de conexin reservados para el superusuario unix_socket_directory = /var/run/postgresql Directorio de los sockets unix para esta instancia de Postgres. Note que con esta directiva se pueden ejecutar mltiples instancias del DBMS. unix_socket_group = Indica el grupo dueo de los sockets unix. unix_socket_permissions = 0777 Indica los permisos en octal de acceso a los sockets unix bonjour_name = Permite establecer el nombre del DBMS. De estar comentado o en blanco, toma el nombre el equipo host Seguridad y Autenticacin #authentication_timeout = 60 # 1-600, in seconds. Tiempo en segundos de espera por la

informacin de login. Desde 1 a 600. #ssl = true Indica si el uso de SSL es forzado. De estar comentado es falso. #password_encryption = on Flag que indica si el uso de encriptacin en el envo de la contrasea es obligatorio o no. De estarcomentado es apagado. #db_user_namespace = off Habilita la funcionalidad donde los nombres de usuario pueden ser especficos de cada base de datos, es decir, usuario@baseEjemplo quiere decir que usuario solo se aplicara a baseEjemplo y no a todas como es por defecto. Uso de Recursos En esta seccin se puede especificar la cantidad de recursos que esta instancia de PostgreSQL estaautorizada a consumir. shared_buffers = 1000 Editando esta opcin es la forma ms sencilla de mejorar el rendimiento del servidor de base de datos. El valor por defecto es muy bajo para la mayora de hardware moderno. Generalmente se dice que debera estar en alrededor del 25% de la memoria RAM disponible en el sistema. En sistemas que tengan menos de 1GB en RAM la proporcin suele ser 15%, dependiendo de la memoria que consume el sistema operativo. En algunas circunstancias se podra requerir ms del 25% pero dado que postgres tambin utiliza la memoria compartida del sistema de operativo los valores tan altos no tienen gran relevancia

frente a los valores bajos. Tenga en cuenta que para sistemas abajo de la versin 8.1 los valores altos en shared_buffers no funcionan bien, en cambio se pueden tener valores de 32MB a cerca de 400MB funcionando correctamente. Como la mayora de las opciones que se resumen aqu, simplemente tendr que probar diferentes valores, hacia arriba y haca abajo, y ver que tan bien funciona el sistema. Muchas personas van fijando valores altos hasta encontrar el valor que degrada el sistema y as ir encontrando el ideal. temp_buffers = 1000 Los buffers temporales hacen referencia a la cantidad de memoria utilizada por cada sesin de base de datos para acceder a tablas temporales. #max_prepared_transactions = 5 Se recomienda dejar por defecto.5 work_mem = 1024 Este valor se debe fijar con relacin al parmetro max_connections, si por ejemplo tiene 400 conexiones simultaneas y fija work_mem en 20MB estar utilizando 8GB de memoria compartida. Tenga en cuenta esta medida y fije el valor suficiente ya que este le permite mejorar el rendimiento de consultas de ordenamiento complejo. Por ejmeplo. maintenance_work_mem = 16384 Esta directiva en kilobytes, indica la cantidad de memoria a utilizar por las labores de mantencin como VACUUM, CREATE INDEX, restauracin de bases de datos, etc. Como no se suelen dar operaciones concurrentes de este tipo dejarlo en un valor como 256MB esta bien. max_fsm_pages = 20000 Esta opcin ayuda a controlar el Mapeo de Espacio Libre ( free space map(FSM)). Cuando algo es eliminado de la tabla no es removido del disco inmediatamente. El espacio es realmente marcado como libre en el FSM. El espacio puede ser reutilizado para cualquier nuevo INSERT realizado en la tabla. Si el sistema tiene una alta tasa de INSERT y DELETE puede ser necesario aumentar este valor para evitar que las tablas aumenten desmesuradamente su tamao. max_fsm_relations = 1000 Cantidad de relaciones (tablas e ndices) de las cuales se mantiene monitoreo del espacio libre en el mapade espacio libre. Deben ser al menos 100 Ajustes a las Consultas (Query Tuning) Configuracin de las funciones del planificador. Desabilite la funcin que necesite pasando a off #enable_bitmapscan = on #enable_hashagg = on

#enable_hashjoin = on #enable_indexscan = on #enable_mergejoin = on #enable_nestloop = on #enable_seqscan = on #enable_sort = on #enable_tidscan = on Costos del planificador #effective_cache_size = 16000MB Este valor le dice al optimizador de PostgreSQL, cuanta memoria tiene asignada PostgreSQL para el almacenamiento de cache de datos y ayuda en el momento de la determinacin de si crear o no un indice. Cuanto mayor sea el valor se incrementa la probabilidad de usar un indice. Asigne la cantidad de memoria que queda luego de determinar la cantidad de memoria que se toma el sistema operativo y las dems aplicaciones que puedan existir(apache, PHP, etc). Esta memoria no es que este asignada realmente sino que es un valor que utiliza el planificador de PostgreSQL para saber si los planes que estn considerando caben en RAM. Establezcalo al 50% de la RAM y an esto es algo conservador. Un 75% se podra tener. #random_page_cost = 4 Controla la forma en que PostgreSQL ve las lecturas de disco no secuenciales. Un valor alto hace que sea ms probable que una bsqueda secuencial pueda ser realizada bajo una bsqueda de indices, indicando que el servidor tiene discos muy rpidos. #cpu_tuple_cost = 0.01 Costo de procesar una fila en una consulta. El valor esta indicado en una fraccin del costo de recuperacin de una pgina secuencial. #cpu_index_tuple_cost = 0.001 Costo de proceso de una fila durante un escaneo va ndice. El valor esta indicado en una fraccin del costo de recuperacin de una pgina secuencial. #cpu_operator_cost = 0.0025 - Costo estimado de procesar cada operador en una clusula WHERE. El valor est indicado en una fraccin del costo de recuperacin de una pgina secuencial.

Optimizador Gentico de Consulta (GEQO Genetic Query Optimizer) PostgreSQL incorpora dentro de su analizador de consultas, un algoritmo gentico para optimizacin de consultas que incorporan JOIN. Las siguientes directrices permiten ajustar el comportamiento de este algoritmo.

Los algoritmos genticos son una optimizacin heurstica que opera de forma nodeterminstica. El set desoluciones posibles para el problema se denomina poblacin, mientras que el grado de adaptacin de un individuo se llama ajuste. Las coordenadas del individuo dentro del espacio de soluciones se representa por cromosomas. Un gene es una subseccin de un cromosoma el cual codifica el valor de un nico parmetrodentro de la optimizacin. Para obtener la solucin se simula la recombinacin y mutacin de los individuos, realizndose la seleccin natural en base a aquel individuo que presenta en promedio un mayor grado de adaptacin que sus ancestros. #geqo = on Habilita o deshabilita el uso del algortmo gentico. #geqo_threshold = 12 Cantidad de elementos en la clusula FROM desde los cuales el algortmo gentico es utilizado. #geqo_effort 0 5 Controla en enteros de 1 a 10, la proporcin de tiempo que el planificador gasta en planificar y la efectivdad del mismo. Valores ms altos resultarn en un tiempo mayor de planificacin, pero tambin aumenta la probabilidad de encontrar un plan ms eficiente. #geqo_pool_size = 0 Cantidad de individuos en la poblacin, debiendo haber al menos 2. De fijarse en 0 se elige un tamao ptimo con base al esfuerzo indicado en geqo_effort #geqo_generations = 0 Controla la cantidad de generaciones(iteraciones) usadas por GEQO. Debe ser al menos 1. Fijando en 0 hace que el motor escoja un valor adecuado con base al esfuerzo indicado en geqo_effort. #geqo_selection_bias = 2.0 Ajusta la presin de seleccin dentro de la poblacin, valor de 1.5 a 2.0. #default_statistics_target = 10 Indica la cantidad de columnas a usar en el anlisis, en consultas que no se especifica o no se ha indicado va ALTER TABLE SER STATISTICS. #constraint_exclusion = off Al estar habilitado compara las condiciones de la consulta con las restricciones de la tabla impuestas en CHECK. #from _collapse_limit = 8 El planificador juntar subconsultas hacia niveles superiores si la lista resultante en la clusula FROM notiene ms elementos que este valor. Valores pequeos resultan en planificaciones ms cortas, pero menosefectivas. Es conveniente dejar este valor bajo gego_threshold. #join_collapse_limit = 8 El planificador rescribir los INNER JOINs de la consulta a items FROM, siempre y cuando el largo de la listaen esa clusula no sobrepase este valor. No tiene

efecto alguno en OUTTER JOINs. Fijar su valor a 1, inhibe la reescritura haciendo el planificador se comporte como la versin 7.3

parmetros de Autovacuum A partir de la versin 8.1 de PostgreSQL, existe un subproceso separado llamado demonio autovacuum. Este es el encargado de revisar peridicamente la tablas con modificacin considerables a su tuplas. Los datos utilizados por el demonio son aquellos generados al estar stats_start_collector y stats_row_levelencendidos. El proceso se conecta a la base de datos utilizando alguno de los slots de superusuario reservados. El subproceso realiza 2 tareas: VACUUM y ANALYZE sobre las tablas que hayan alcanzado el nivel de cambio indicado por autovacuum_vacuum_threshold y autovacuum_analyze_threshold respectivamente. autovacuum = on Indica si ejecutar el proceso autovacuum o no #autovacuum_naptime = 1 min Tiempo que duerme el proceso de autovacuum entre ejecuciones #autovacuum_vacuum_threshold = 500 Umbral para determinar cuando se aplica VACUUM a una tabla. Cuando el valor calculado de la base ms la cantidad de filas modificadas multiplicadas por el factor supera este valor, entonces se ejecuta VACUUM sobre la tabla. #autovacuum_analyze_threshold = 250 Umbral para determinar cuando se aplica ANALYZE a una tabla. Cuando el valor calculado de la base ms la cantidad de filas modificadas multiplicadas por el factor supera este valor, entonces se ejecuta ANALYZE sobre la tabla. #autovacuum_vacuum_scale_factor = 0.2 Factor por el cual se multiplican la cantidad de filas modificadas de una tabla para obtener el umbral de ejecucin de vacuum sobre esta tabla. #autovacuum_analyze_scale_factor = 0.1 Factor por el cual se multiplican la cantidad de filas modificadas de una tabla para obtener el umbral de ejecucin de analyze sobre esta tabla. Estas son las principales opciones de configuracin de PostgreSQL que impactan notoriamente el rendimiento de la base de datos. Evalue y ajuste hasta que encuentre la configuracin de mayor rendimiento para sus necesidades. Cuestiones de Hardware

Obviamente el tipo y la calidad de Hardware que se usa impacta drasticamente el rendimiento de la base de datos. Estos son algunos consejos a la hora de comprar hardware para su servidor de base de datos, en orden de importancia:

RAM Entre ms RAM se tenga debe tener ms cache de disco. Esto afecta en gran medida el rendimiento teniendo en cuenta que la memoria de E / S es miles de veces ms rpida que la E / S del disco. Disk types Definitivamente los rpidos discos SCSI Ultra-320 son la mejor opcin. Sin embargo los discos SATA de alta gama tambin son muy buenas. Los discos SATA son mucho ms econmicos y con ellos se pueden tener muchos ms ejes en su estructura de almacenamiento por el mismo precio. Disk configuration La confuguracin ms ptima es RAID 1+0 con tantos discos como sea posible y con le registro de transacciones (pg_xlog) en un disco independiente, bien sea fsico o viertual(Stripe Disk). RAID 5 no es una opcin recomendada a no ser que tenga ms de 6 discos en su volumen. Con las nuevas versiones de PostgreSQL se puede utilizar la opcin de tablespace para poner tablas, base de datos e indices en discos diferentes para mejorar el dendimiento. As como poner las tablas de uso frecuente en un disco SCSI y las menos utilizadas en discos ms lentos SATA o IDE. CPUs Entre mejor CPU se tenga mejor rendimiento, sin embargo, si su base de datos no utiliza muchas funciones complejas es mejor invertir el dinero en ms memoria RAM o un mejor sistema de discos.

En general cuanto ms RAM se tenga y ms posibilidad de conexiones de disco el sistema funcionar mejor. Esto por que entre ms RAM exista menos acceso al disco se realiza y entre ms conexiones de disco existan disponibles es posible distribuir las operaciones de lectura y escritura en disco, aumentando el rendimiento y disminuyendo los cuellos de botella. Otra buena idea es separar el cdigo de la aplicacin de la base de datos en diferente hardware. Esto significa que no solo se va a tener ms hardware disponible para la base de datos sino que la memoria cache del sistema operativo contendr ms datos PostgreSQL y no de otro tipo de aplicaciones o procesos. Por ejemplo, si usted tiene un servidor web y un servidor de base de datos se puede usar un cable cruzado por interfaces de redes exclusivas para que estos dos se comuniquen y a su vez el servidor web utiliza otra conexin diferente para comunicarse con sus clientes. Si son varios servidores web accediendo a un mismo servidor de base de datos podra armar una red independiente y esclusiva para este trfico. Una vez tengamos la mejor configuracin es ideal revisar todo tipo de consultas que recibe la base de datos y ver en que medida se puede mejorar su rendimiento. Para iniciar debe ubicar las

consultas ms repetitivas y las que ms consumen tiempo de ejecucin. En otro articulo puede encontrar ms informacin de como ubicar este tipo de consultas. Herramientas tiles para realizar Tuning a las Consultas La herrmienta ms usada para realizar Tuning a la base de datos es el comando SQL EXPLAIN ANALYZE. Este permite ver el registro de cada consulta SQL que es llevada a cabo y ver exactamente como el planificador de PostgreSQL procesa cada consulta. Veamos este ejemplo:
CREATE TABLE authors ( id name ); int4 PRIMARY KEY, varchar

CREATE TABLE books ( id title ); Si usamos la consulta


EXPLAIN ANALYZE SELECT authors.name, books.title FROM books, authors WHERE books.author_id=16 and authors.id = books.author_id ORDER BY books.title;

int4 PRIMARY KEY, varchar

author_id int4,

Se obtiene una salida como esta


QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- Sort (cost=29.71..29.73 rows=6 width=64) ( actual time=0.189..16.233 rows=7 loops=1) Sort Key: books.title -> Nested Loop (cost=0.00 ..29.63 rows=6 width=64) (actual time=0.068..0.129 rows=7 loops=1) -> Index Scan using au thors_pkey on authors (cost=0.00..5.82 rows=1 width=36) (actual time=0.029..0.033 rows=1 loops=1) Index Cond: (id = 16) -> Seq Scan on books (cost=0.00..23.75 rows=6 width=36) (a ctual time=0.026..0.052 rows=7 loops=1) Filter: (author_id = 16) Total runtime: 16.386 ms

La salida se debe analizar de abajo hacia arriba. Lo primero que hace PostgreSQL es una bsqueda secuencial sobre la tabla books ubicando la colmna author_id con un valor igual a 16. Luego se hace un recorrido al indice de la tabla authors, el mismo indice que es creado por la PRIMARY KEY. Finalmente los resultados son ordenados por el campo books.tittle

Los valores que se ven en parntesis son el costo estimado y actual de esa parte de la consulta. Cuanto menor sea la diferencia entre estos dos valores existeme un mejor desempeo. Ahora vamos a cambiar un poco la estructura con la adicin de un Index en books.author_id y as evitar la busqueda secuencial.
CREATE INDEX books_idx1 on books(author_id);

Si se vuelve a ejecturar la consulta de nuevo usted no vera ningn cambio notable en la salida. Estos es por que PostgreSQL no ha vuelto a analizar los datos y no ha determinado que el nuevo index puede ayudar en la consulta. Esto se puede solucionar mediante la ejecucin de:
ANALYZE books;

Puede que no note cambios en los resultados de la bsqueda en secuencia si la tabla no contiene muchos registros. Si una consulta va a retornar una gran cantidad de datos, el planificador selecciona una bsqueda en secuencia a travs del indice, ya que es ms rpido. Se puede forzar PosgreSQL a favor de las bsquedas por indices sobre las bsquedas secuenciales fijando el parmetro de configuracin enable_seqscan = off . Esto no quita todas las bsquedas por secuencia ya que algunas tablas pueden no tener indices pero si fuerza al planificador a utilizar siempre una bsqueda por indices cuando estos estn disponibles y sin importar si la cantidad de datos a retornar es mnima. Es recomendable hacer este cambio en la parte inicial de cada conexin con a la base de datos, por medio del comando SET enable_seqscan = off , y no hacerlo ampliamente en todas las bases de datos. Sin embargo desactivas esta opcin se hace en casos de pruebas y de realizacin de Tuning y no como opcin de uso diario. Generalmente la mejor forma de optimizar las consultas es usar indices en colmnas especficas y combinaciones de colmnas que corresponden a las consultas ms frecuentes. Lamentablemente esto se hace por ensayo y error. Tambin debe tener en cuenta que incrementar el nmero de indices en una tabla incrementa el nmero de operaciones de escritura que se deben realizar para cada INSERT y UPDATE. As que no haga cosas tontas como agregar indices a todas las colmnas de una tabla. Algo que puede ayudar es jugar con el nivel de las estadsticas que se recogen en una tabla o columna con el comando:
ALTER TABLE <table> ALTER COLUMN <column> SET STATISTICS <number>;

Este valor puede ser un nmero entre 0 y 1000 y ayuda a PostgreSQL a determinar el nivel de recopilacin de estadsticas que se debe realizar en esta columna. Esto ayuda a controlar la

generacin del plan de la consulta sin tener VACUUM lentos y analizar las operaciones debido a la generacin de grandes cantidades de estadsticas para todas las tablas y columnas. Otra herramienta til para ayudar a determinar como hacer Tuning a la base de datos son las consultas al registro del sistema. Se puede decir a PostgreSQL que consultas del registro nos interesan a travs de la opcin de configuracin de log_statement. Esto es muy til en situaciones donde hay muchos usuarios realizando consultas tipo ad hoc() en el sistema a travs de algo como Crystal Reports o directamente va PSQL. Diseo y estructura de la base de datos A veces el diseo y la estructura de la base de datos afecta el rendimiento. Por ejemplo si usted tiene una tabla como la que se muestra a continuacin:
CREATE TABLE employees ( id int4 PRIMARY KEY, active boolean, first_name varchar, middle_ name varchar, last_name varchar, ssn varchar, address1 varchar, address2 varchar, city va rchar, state varchar(2), zip varchar, home_phone varchar, work_phone varchar, cell_phone varchar, fax_phone varchar, pager_number varchar, business_email varchar, personal_email varchar, salary int4, vacation_days int2, sick_days int2, employee_number int4, office_ad dr_1 varchar, office_addr_2 varchar, office_city varchar, office_state varchar(2), office _zip varchar, department varchar, title varchar, supervisor_id int4 );

El diseo es fcil de entender, pero no es muy bueno en varios niveles. Si bien depender de la aplicacin en particular, en la mayora de casos usted no nececita acceder a todos los datos al mismo tiempo. Al romper esta tabla en tablas ms pequeas se puede conseguir que las consultas sean ms eficientes ya que PostgreSQL tiene que leer menos y eso sin tocar otros aspectos de funcionalidad. Esta es una mejor manera de hacer las cosas:
CREATE TABLE employees ( id int4 PRIMARY KEY, active boolean, employee_number int4, first _name varchar, middle_name varchar, last_name varchar, department varchar, title varchar, email varchar ); CREATE TABLE employee_address ( id int4 PRIMARY KEY, employee_id int4, p ersonal boolean, address_1 varchar, address_2 varchar, city varchar, state varchar(2), zi p varchar ); CREATE TABLE employee_number_type ( id int4 PRIMARY KEY, type varchar ); CRE ATE TABLE employee_number ( id int4 PRIMARY KEY, employee_id int4, type_id int4, number v archar ); CREATE TABLE employee_hr_info ( id int4 PRIMARY KEY, employee_id int4, ssn varc har, salary int4, vacation_days int2, sick_days int2 );

De esta manera esta unidad de informacin esta divida en grupos lgicos. La tabla principal contiene la informacin ms utilizada y las otras tablas almacenan el resto de informacin. El beneficio adional de este diseo es que puede tener cualquier cantidad de telfonos y direcciones asociadas a un solo empleado de la tabla principal.

Otro consejo til es utilizar los indices parciales en las columnas donde se consulta un cierto valor con mayor frecuencia que otros. Tomemos, por ejemplo, la tabla empleados de arriba. probablemente casi siempre se consultan los empleados que tengan estado activo, pero creando un indice parcial para la columna cuando el valor es verdadero ayuda a incrementar la velocidad de la consulta y puede ayudar a que el planeador decida usa el index en los casos en que de otro modo no lo hara. Un index parcial se puede crear de la siguiente manera:
CREATE INDEX employee_idx2 ON employee(active) WHERE active='t';

Otros articulos relacionados a este y que le pueden ser de inters son: Sistema de Bitcoras(Logs) en PostgreSQL Compilando y poniendo en marcha PostgreSQL Aspectos de Seguridad en PostgreSQL

Segunda Investigacin

Algunos consejos generales para aumentar el rendimiento


Dom, 29/03/2009 - 22:30 rafaelma

Como hemos dicho muchas veces, no existe siempre la solucin perfecta para aumentar el rendimiento de nuestro sistema. Las bases de datos son sistemas dinmicos que se utilizan de diferentes maneras y contienen diferentes tipos de datos. Una configuracin que funciona bien con un sistema, no tiene porque hacerlo con otro y existen muchos factores que pueden afectar positiva y negativamente al rendimiento. Pero existen diferentes tcnicas que se pueden usar aisladas en conjunto que ayudan en muchos casos a mejorar el rendimiento. Aqui teneis una pequea lista con algunos consejos generales que suelen ayudar en muchas ocasiones cuando se necesita

mejorar el rendimiento. En esta lista no tendremos en cuanta las mejorias que se pueden obtener con el uso adecuado de SQL y normalizacin de los datos. Ejecutar VACUUM ANALYZE tan a menudo como sea necesario, Bien manualmente ajustanto autovacuum si es necesario Un sistema de discos de alto rendimiento suele ser ms importante que la cantidad de memoria disponible y esta a su vez ms importante que la CPU utilizada. Un servidor de bases de datos nunca tendra suficiente memoria. Cuanta ms memoria, mejor. Cuanto ms discos disponibles en RAID, mejor. Usar Tablespaces para organizar los datos. RAID 1+0 / 0+1 suele funcionar mejor que RAID 5. Saparar el registro de transacciones (ficheros WAL) del resto de datos, usar diferentes discos. Aumentar el valor de checkpoint_segments en sistemas con una alta concurrencia de actualizaciones de los datos (insert,update,delete) Discos SCSI y SAS som preferibles en servidores con un alto nivel de utilizacin Mltiples CPUs ayudan a ejecutar/realizar trabajos paralelos en nuestras bases de datos. Ejecutar CLUSTER cuando sea viable en tablas con una alto nivel de actualizacin de datos. Utilizar un servidor dedicado siempre que sea posible. Ser ms facil de configurar y ajustar para mejorar nuestro rendimiento. Al inicializar/poblar una nueva base de datos con una gran cantidad de datos: o o o o o o Usar COPY en vez de INSERT Remover los indices durante la restauracin de los datos. Aumentar el valor de Aumentar el valor de
maintenance_work_mem checkpoint_segments

fsync=false !! No olvidar cambiar este valor a TRUE cuando termineis de restaurar los datos !! No olvidar ejecutar ANALYZE al termino de la restauracin de los datos

Bueno, y hasta aqui los consejos generales, ms adelante iremos profundizando en aspectos concretos que pueden afectar al rendimiento.

Tercera Investigacin

Aumentar el rendimiento Postgres


Muchas personas piensan que el aumento de rendimiento de una Base de Datos es sinonimo de CPU, es decir mientras mejor es la CPU mejor es el rendimiento. Esto no es cierto porque existen variantes ms importantes que considerar al momento de tratar de sacar el mejor provecho a nuestra Base de Datos.

1. 2. 3. 4. 5.

Para empezar se debe usar Servidores Dedicados para Bases de Datos, muchas pymes utilizan los Servidores como equipos de almaceanamiento, lo cual hace que un servidor llegue a ser Servidor de Archivo, Correo y Base de Datos al mismo tiempo, cuando fallan los sistemas siempre el culpable es la Base de Datos. Actualizar a la ultima version de postgres, siempre es importante ir actualizando los sistemas a la ultima version de Postgres (8.3 para produccion y 8.4 beta 2), para obtener un mejor rendimiento, superara lo bug y no tener que lamentar problema indeseados. Levantar un Servidor en linux, esta comprobado que Postgres obtiene el mejor rendimiento con los Sistemas Operativos LINUX, eso no quiere decir que en Windows esto funcione mal. La seleccin del tipo de disco a utilizar, es recomendable discos Duros de alto rendimiento ojalas en RAID o para las empresas pequeas SATA. Utilizar la major cantidad de Memoria RAM posible. Separar el fichero de Datos y Log, en unidades de Disco diferentes. Para concluir es necesario que revisen los siguientes parametros max_connections: aplica la cantidad mxima de conexiones de clientes shared_buffers: determina cuanta memoria est dedicada a PostgreSQL para datos en cach effective_cache_size:Este debe ser establecido en un monto estimado de cuanta memoria est disponible para memoria intermedia en el disco para el sistema operativo checkpoint_segments:PostgreSQL escribe las nuevas transacciones a la Base de Datos en un archivo llamado segmentos del WAL que son de 16MB de tamao autovacuum:Vaccum significa 'vaciar' literalmente hablando. El proceso de VACUUM lo que realiza es una limpieza de tuplas muertas que han sido marcadas como borradas o modificadas, ya que el motor de base de datos no las borra inmediatamente de la parte fsica para no sobrecargar las operaciones normales para major informain sobre estos parametros, diriguirse a wiki de postgres

Otros consejos para lograr una mejor optimizacin aqui (esta en ingles) link interesantes: Encontrando consultas que Consumen Recursos Optimizacin del rendimiento (esta en ingles)