Mejorando el rendimiento de las bases de datos (3)

1 comentario

En artículos previos ya habíamos visto algunos métodos que podemos usar para mejorar el rendimiento de nuestras bases de datos ya que lo usual es que deseemos obtener más velocidad para todas las operaciones (inserciones, actualizaciones, borrados, consultas).

En cuando al Sistema Operativo a usar podemos leerlo en este enlace:

https://firebird21.wordpress.com/2013/08/15/cual-sistema-operativo-usar-en-el-servidor/

Administración:

En este apartado veremos lo que puede hacer el Administrador de la Base de Datos para que ésta funcione mejor. Una de las tantas cosas buenas que tiene Firebird es que no necesita de un Administrador dedicado exclusivamente a su tarea, como sí es el caso de Oracle o de SQL Server. Las bases de datos de Firebird requieren de un mantenimiento mínimo, pero de todas maneras requieren de mantenimiento, aunque sea de vez en cuando. Las tareas básicas del Administrador son:

  1. Detectar y eliminar las transacciones que demoran mucho en finalizar
  2. Hacer un barrido manual
  3. Hacer un backup y verificar que funcione
  4. Verificar los identificadores de las transacciones
  5. Verificar las estadísticas de los índices y reconstruirlos si es necesario

1. Detectando y eliminando transacciones que demoran mucho en finalizar

Lo que más puede degradar el rendimiento de las bases de datos es que se actualicen o se borren filas y que la transacción que actualizó o borró esas filas no termine con un COMMIT o con un ROLLBACK.

Una transacción que no terminó ni con un COMMIT ni con un ROLLBACK para el Firebird continúa activa, aunque hayan pasado días, semanas, o meses. Y continúa activa porque el Firebird no puede saber, no puede adivinar, si la transacción no finalizó porque el Desarrollador no quiere que finalice aún o porque el Desarrollador se olvidó de escribir un COMMIT o un ROLLBACK. Como el Firebird no es adivino entonces por las dudas mantiene a la transacción abierta, no la cierra por su propia cuenta ya que cerrar la transacción es competencia exclusiva del Desarrollador, no del Firebird.

Entonces, una de las tareas del Administrador de la Base de Datos es verificar si hay transacciones que están activas desde hace mucho tiempo. En una aplicación bien programada ninguna transacción debería tardar más de unos cientos de milisegundos en finalizar. Si una transacción tarda más de un segundo eso ya debería llamar la atención a cualquier Administrador competente. Y ni que hablar si hace horas o días que está activa. Para saber como detectar y eliminar las transacciones que están activas desde hace mucho tiempo puedes leer estos artículos:

https://firebird21.wordpress.com/2013/03/02/detectando-aplicaciones-y-usuarios-que-mantienen-las-transacciones-abiertas-durante-mucho-tiempo/

https://firebird21.wordpress.com/2013/05/07/detectando-una-consulta-que-esta-tardando-mucho/

Aunque el título del último artículo dice “detectando una consulta” en realidad se refiere a transacciones.

Después de detectar y eliminar la transacción problemática hay que buscar y encontrar el motivo. ¿Por qué esa transacción demoró tanto? ¿Cuál es el programa que inició esa transacción? ¿por qué no finalizó ni con un COMMIT ni con un ROLLBACK?

Aquí, el Administrador debe comunicarse con el Desarrollador para informarle del problema que encontró y pedirle que lo solucione a la brevedad posible.

2. Haciendo un barrido manual

El barrido (sweep, en inglés) debe hacerse sí o sí cuando la diferencia entre la OST y la OAT es grande. Aquí, la palabra “grande” depende del contexto. Por defecto el Firebird inicia el sweep cuando esa diferencia es mayor que 20.000 pero ese número puede ser cambiado si se lo desea. Lo importante a recordar es que el sweep es un proceso que consume muchísimos recursos y en consecuencia todas las operaciones con la Base de Datos pueden volverse lentísimas. Es por ese motivo que la mayoría de los Administradores ponen el intervalo del sweep en 0 (cero) para realizarlo de forma manual, porque si se inicia de forma automática entorpecerá las actividades normales de los usuarios desde que empieza hasta que finaliza (según la conocida Ley de Murphy empezará en el peor momento posible, cuando más velocidad necesitan los usuarios), lo cual puede demorar horas en una Base de Datos muy grande y con mucha basura acumulada. Es por eso que muchos Administradores hacen el sweep en horarios en que nadie está usando la Base de Datos (y si eso no es posible, entonces en un día y hora en que muy pocas personas la están usando).

Puedes leer más sobre el sweep en este artículo:

https://firebird21.wordpress.com/2013/09/11/entendiendo-sweep-y-garbage-collection/

Resumiendo:

a) Si no se hace el sweep y la diferencia entre la OST y la OAT es grande entonces todas las operaciones se volverán muy lentas.

b) Mientras se está haciendo el sweep todas las operaciones se vuelven muy lentas

Recomendación:

Hacer el sweep cuando nadie está usando la Base de Datos o cuando muy pocas personas la están usando.

3. Haciendo un backup y verificando que funcione

Tener backups actualizados es algo tan elemental que supongo que no es necesario abundar sobre ese tema. Ningún profesional de la Informática tiene la menor duda al respecto.

Pero la tarea del Administrador no se limita a hacer backups, también debe verificar que ese backup pueda ser restaurado exitosamente. ¿Por qué? porque no hay algo peor que creer que se tiene un backup actualizado y a la hora de restaurarlo se descubre que no es posible lograrlo, que está dañado y es inútil e inservible.

Una regla muy conveniente para seguir es la siguiente:

    • Se hace un backup
    • Se lo restaura para asegurarse de que funciona
    • Se copia el backup en otro dispositivo y se lo lleva lejos de la computadora donde se encuentra el Servidor

De lo anterior se deduce que siempre tendremos al menos dos backups idénticos. Uno de ellos se mantendrá cerca del Servidor para poder restaurar rápidamente la Base de Datos en caso de ésta tener algún problema. El otro backup se mantendrá lejos del Servidor (en otro edificio o inclusive en otra localidad) para poder restaurar la Base de Datos en caso de catástrofe (terremoto, incendio, inundación, explosión de una bomba, robo de la computadora, etc). También es muy conveniente tener una copia en Internet. En esta época hay muchos sitios que permiten almacenar archivos grandes (MediaFire, Mega, RapidShare, DropBox, etc.) y tener el backup guardado en ellos es muy conveniente porque permiten que ese backup sea recuperado aún en el caso de ocurrir una catástrofe.

Si el backup se hace con el programa GBAK.EXE se tienen además otras ventajas:

    • El backup no tiene basura porque la basura no se  guarda en el backup
    • Cuando se restaura el backup se reconstruyen los índices así que al finalizar la restauración los índices estarán perfectos

4. Verificando los identificadores de las transacciones

Todo buen Administrador debe verificar periódicamente los identificadores de las transacciones porque como sabemos así se puede detectar si la Base de Datos tiene mucha basura. Puedes leer más en este artículo:

https://firebird21.wordpress.com/2013/09/08/entendiendo-los-identificadores-de-las-transacciones/

5. Verificando las estadísticas de los índices y reconstruyéndolos

Los índices pueden ir degradándose, eso ocurre frecuentemente cuando en una tabla se actualizaron o se borraron muchas filas. Por ese motivo es conveniente reconstruirlos de vez en cuando, puedes leer más en estos artículos:

https://firebird21.wordpress.com/2013/03/02/mantenimiento-de-indices/

https://firebird21.wordpress.com/2013/03/03/recreando-los-indices-de-las-tablas/

https://firebird21.wordpress.com/2013/03/09/selectividad-de-los-indices/

https://firebird21.wordpress.com/2013/08/24/usando-indices-en-firebird/

Conclusión:

Aunque afortunadamente Firebird no requiere que una persona trabaje exclusivamente como Administrador de las Bases de Datos, sí hay tareas que deben realizarse de vez en cuando para asegurarse de que las bases de datos se encuentren en un buen estado operativo, de lo contrario se irán degradando y el rendimiento decaerá. Si todo se realiza de la forma correcta, la tarea del Administrador no demorará más que unos cuantos minutos cada día e inclusive si la empresa u organización no es muy grande el trabajo podría ser de unos cuantos minutos a la semana o al mes.

Si todas las transacciones son cortas, todas las transacciones finalizan con un COMMIT o con un ROLLBACK, se hacen backups y restauraciones diarios, entonces nunca deberías tener problemas y todo debería funcionar de maravillas.

Pero no te olvides que tú o alguien más debe dedicarle un poco de tiempo a la tarea de Administrar la Base de Datos, solamente el ojo humano puede detectar fallas, eso es algo que no se puede automatizar.

Artículos relacionados:

¿Cual Sistema Operativo usar en el Servidor?

Detectando aplicaciones y usuarios que mantienen las transacciones abiertas durante mucho tiempo

Detectando una consulta que está tardando mucho

Entendiendo sweep y garbage collection

Entendiendo los identificadores de las transacciones

Mantenimiento de índices

Recreando los índices de las tablas

Recreando todos los índices de todas las tablas

Recreando índices y calculando estadísticas

Selectividad de los índices

Usando índices en Firebird

El índice del blog Firebird21

Un error al usar la cláusula GROUP BY

Deja un comentario

Como seguramente sabes, cuando escribes un SELECT puedes agrupar los datos que obtendrás como resultado si utilizas la cláusula GROUP BY. Esto es muy útil en muchas ocasiones pero también a veces podrías encontrarte con un error y no entiendes el motivo. Aquí se muestra uno de esos casos.

Este artículo está basado en una consulta que respondieron Dimitry Sibiryakov y Dmitry Yemanov, desarrolladores de Firebird.

Supongamos que quieres usar COLLATE para indicarle al Firebird el orden en que debe aparecer el texto dentro de una columna CHAR o VARCHAR.

Un SELECT que sí funciona

SELECT
   CLI_NOMBRE COLLATE ES_ES_CI_AI
FROM
   CLIENTES
GROUP BY
   CLI_NOMBRE
ORDER BY
   CLI_NOMBRE

Otro SELECT que sí funciona

SELECT
   CLI_NOMBRE COLLATE ES_ES_CI_AI
FROM
   CLIENTES
GROUP BY
   CLI_NOMBRE COLLATE ES_ES_CI_AI
ORDER BY
   CLI_NOMBRE COLLATE ES_ES_CI_AI

Un SELECT que no funciona

SELECT
   CLI_NOMBRE
FROM
   CLIENTES
GROUP BY
   CLI_NOMBRE COLLATE ES_ES_CI_AI
ORDER BY
   CLI_NOMBRE COLLATE ES_ES_CI_AI

Al ejecutar el tercer SELECT el Firebird muestra el mensaje:

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).

¿Por qué, qué pasó? ¿Por qué los dos primeros SELECT funcionaron bien y el tercero no?

El primero funcionó bien porque está agrupado por el valor original.

El segundo funcionó bien porque se usa el mismo COLLATE en el resultado y en el grupo. Siempre que uses exactamente los mismos valores en el resultado y en el grupo, funcionará.

Sin embargo, el tercero es diferente porque en el resultado se desea obtener el valor original pero se lo agrupa por el COLLATE y eso es contradictorio, ya que el agrupamiento siempre debe hacerse por el valor original o por un valor que lo incluya. Y como en el tercer ejemplo no es así, por eso obtendrás el error que se mostró arriba.

El problema puede ser más fácil de entender con los siguientes ejemplos:

  1. SELECT SIN(X) … GROUP BY X
  2. SELECT SIN(X) … GROUP BY SIN(X)
  3. SELECT X … GROUP BY SIN(X)

No puedes pedir que te muestre la columna X y que la agrupe por el seno de X ya que algo así no tiene sentido. Piensa en COLLATE como si se tratara de una especie de CAST. Al hacer un COLLATE se sobreescriben las reglas de la comparación y por lo tanto “MiColumna” y “MiColumna COLLATE ES_ES_CI_AI” pueden producir diferentes agrupamientos. Por ejemplo:

COLLATE1

Captura 1. Si haces clic en la imagen la verás más grande

En la Captura 1 vemos los datos de los empleados, tal y como fueron cargados en la tabla.

SELECT
   EMP_NOMBRE
FROM
   EMPLEADOS
GROUP BY
   EMP_NOMBRE

COLLATE2

Captura 2. Si haces clic en la imagen la verás más grande

En la Captura 2 vemos el resultado de escribir un SELECT sin COLLATE. Nos muestra los datos agrupados como fueron cargados.

SELECT
   EMP_NOMBRE COLLATE ES_ES_CI_AI
FROM
   EMPLEADOS
GROUP BY
   EMP_NOMBRE COLLATE ES_ES_CI_AI

COLLATE3

Captura 3. Si haces clic en la imagen la verás más grande

En la Captura 3 vemos el resultado de usar la cláusula COLLATE. Como puedes ver se obtiene un resultado diferente y además el nombre de la columna cambió a CAST. Eso significa que internamente para el Firebird el COLLATE es una especie de CAST. Y también explica el motivo por el cual obtuvimos un error en nuestro tercer SELECT: porque la cláusula GROUP BY requiere que la lista de columnas en el SELECT y la lista de columnas en el GROUP BY sean exactamente las mismas expresiones; y cuando no es así muestra un mensaje de error.

Artículo relacionado:

El índice del blog Firebird21

Mejorando el rendimiento de las bases de datos (2)

5 comentarios

En este artículo ya habíamos visto en forma general lo que debes hacer para que las operaciones con tus bases de datos sean lo más rápidas posibles:

https://firebird21.wordpress.com/2014/02/08/mejorando-el-rendimiento-de-las-bases-de-datos-1/

Ahora, iremos un poco más allá para detallar las características que debe tener el Hardware utilizado.

Recuerda que estamos hablando de un ideal, de lo que elegiríamos si el dinero no es problema, y pudiéramos pagar lo que sea para comprar el hardware y los honorarios del personal encargado de realizar las instalaciones. En la vida real muy raramente conseguiremos llegar a este ideal porque para la mayoría de las empresas el dinero sí es un problema.

Debes prever que casi todas las empresas van creciendo así que el hardware que instales no solamente debe responder a las necesidades actuales sino también para las que se tendrán dentro de los siguientes 3 años. ¿Por qué 3 años? Primero, porque no puedes estar pidiendo dinero para mejorar el hardware cada pocos meses, los gerentes se cansarán de tí, pero cada 3 años sí es razonable. Segundo, porque aunque ahora compres lo mejor de lo mejor es seguro que dentro de 3 años ya estará lejos de ser lo mejor y deberá renovarse. Esto significa que debes prever tanto los incrementos en los tamaños de las bases de datos como también el incremento en la cantidad de computadoras conectadas y el incremento en la cantidad de usuarios concurrentes y que tendrás muchas conexiones vía Internet.

Hardware

  1. La computadora donde se encontrarán las bases de datos debe utilizarse solamente para guardarlas y para nada más. Ningún software no relacionado con Firebird debería instalarse allí. Ni siquiera antivirus. Nada. Solamente el Sistema Operativo y el Firebird y las herramientas de administración del Firebird y las bases de datos. Nada más.
  2. Se necesitarán dos computadoras: una, la de uso normal, de todos los días. Otra, para que sirva de respaldo si la primera por algún motivo sufre desperfectos. Una empresa no puede detener sus operaciones porque la computadora donde se encuentra el Servidor de sus bases de datos se ha dañado. Eso es inadmisible. Por lo tanto, se necesitarán dos computadoras idénticas: una, que se usará todos los días; otra, que se usará solamente si la primera tiene problemas de hardware.
  3. Motherboard. En castellano “tarjeta madre” o “tarjeta principal”. Es la tarjeta más importante de la computadora, a esta tarjeta se conectan todas las demás. Debes comprar la más avanzada disponible, generalmente cuanto más nueva sea, mejor. Debes elegir una que sea “motherboard for server” porque para nuestro objetivo son mucho mejores que las “motherboard for desktop”.
  4. Procesador. Es el cerebro de la computadora. Los tres principales puntos a considerar son: a) Velocidad del reloj: Se mide en Gigahertz (GHz) y nos indica la velocidad con la cual se realizan las operaciones. Cuanto más rápido sea, mejor, porque la velocidad en que se obtienen los resultados de las consultas aumentará. b) Cantidad de núcleos o en inglés “cores”. Mayor cantidad es mejor porque cada núcleo se puede destinar a una tarea: por ejemplo, un núcleo para las operaciones normales con las bases de datos, otro núcleo para los ordenamientos temporales, otro núcleo para hacer los backups. Pero hasta el momento de escribir este artículo con Firebird nunca usarás más de 4 núcleos, así que tener más de 4 es innecesario y una pérdida de dinero. c) Tamaño del caché: cada núcleo tiene una memoria interna de muy alta velocidad a la cual se le llama “memoria caché”. Cuanto mayor sea el tamaño de la memoria caché, mejor, porque se podrán realizar más operaciones en ella, y esas operaciones son las más veloces que pueden realizarse en una computadora.
  5. Memoria RAM. Cuanto más, mejor. Hay un viejo dicho: “la memoria RAM nunca sobra”. Y es que tanto el Sistema Operativo como el Firebird tratan de aprovechar toda la memoria RAM disponible para realizar sus tareas. Cuando la cantidad de memoria RAM es insuficiente eso obliga al Sistema Operativo y al Firebird a utilizar el disco duro, el cual es miles de veces más lento que la memoria RAM. Si hay algo en lo cual no debes escatimar el dinero es en comprar memoria RAM. Siempre compra lo máximo que puedas comprar. Como mínimo deberías tener 4 veces más memoria RAM que el tamaño de todas tus bases de datos combinadas. Por ejemplo, si el tamaño de las bases de datos es de 3 gigabytes entonces tu memoria RAM debería ser al menos de 12 gigabytes. Pero como el tamaño de las bases de datos siempre va en aumento entonces debes tener suficiente memoria RAM para que dentro de 3 años cuando hagas la renovación sigas teniendo al menos 4 veces más memoria RAM que la suma del tamaño de todas tus bases de datos. Eso significa que si prevés que dentro de 3 años las bases de datos ocuparán 10 gigabytes ahora deberías tener al menos 40 gigabyes de memoria RAM.
  6. Disco duro. Los discos de estado sólido (SSD o SSHD) son los más rápidos de todos y además tienen la ventaja de que si se caen no habrá pérdida de datos. Sin embargo el problema con los SSD es que si fallan lo hacen sin previo aviso, un día funcionan perfectamente, al otro día murieron y no tuviste ninguna advertencia; otro problema con ellos es que el rendimiento depende del espacio libre, cuanto más lleno está el disco SSD más lento es, por eso son una maravilla cuando están casi vacíos pero cuando están casi llenos dejan mucho que desear. La conexión a través de PCI Express alcanza velocidades de más de 1 GB por segundo, por lo tanto es mucho más rápida que la conexión por SATA que no suele sobrepasar los 600 MB por segundo y en consecuencia debe ser la elegida,
  7. RAID. Son las siglas de Redundant Array of Independent Disks. Lo que hace es tener a varios discos (duros o SSD) y tratarlos lógicamente como si fueran uno solo. Es decir, para el Sistema Operativo hay un solo disco pero en realidad hay varios. Los datos se escriben en varios discos a la vez para que si ocurre un error en alguno de ellos los usuarios ni se enteren ya que cualquier dato que necesiten se obtendrá de los otros discos. En síntesis, cuando se escribe la escritura se realiza en todos los discos pero cuando se lee se intenta con el primer disco, si la lectura falló, se intenta con el segundo disco y así sucesivamente. Desde luego que si alguno de los discos está fallando el rendimiento disminuye pero la ventaja de tener RAID es que se puede reemplazar al disco defectuoso por uno nuevo sin detener las operaciones con las bases de datos.
  8. Tarjeta de red. Esta es una de las piezas más importantes de cualquier red LAN porque se encarga de administrar el tráfico entre el Servidor y las demás computadoras. No importa cuan rápido sea el disco ni cuanta memoria RAM tengas, si las tarjetas de red son lentas entonces todo será lento ya que todos los datos pasan por ellas. Como mínimo debería ser de 1000 Mbits por segundo.
  9. Fuente de poder. Un Servidor hace un uso súper intensivo del todo el hardware que tiene a su disposición así que debes considerar que los usará a todos al mismo tiempo. Por ejemplo, cada disco del RAID utiliza una cantidad “x” de vatios cuando está en uso. No te olvides de sumar el consumo en vatios de todos los dispositivos conectados. Al total que obtengas agrégale un 20% y con eso ya estará bien.
  10. Router. Además de cuanto más rápido, mejor, también debes verificar que soporte DHCP. Esto permite asignarle a cada computadora de la LAN una dirección IP estática y así siempre sabrás cual es la dirección IP de cada computadora. También que soporte VPN (Virtual Private Network), lo cual es muy útil para que cuando alguien se conecte a través de una notebook esa conexión sea segura. Por supuesto que debe ser full-duplex porque eso dobla la velocidad de transferencia de los datos
  11. Cable de red. El más rápido (al momento de escribir este artículo) es el Cat6a (significa: Categoría 6 aumentada) que permite velocidades superiores a los 10 Gbits por segundo y frecuencias de 500 MHz. La longitud nunca debe ser superior a los 100 metros.
  12. Firewall por hardware. Los firewall pueden ser por hardware o por software. En el caso de una empresa debería ser por hardware porque un solo firewall protege a todas las computadoras de la empresa y además es mucho más sencillo de mantener y de administrar.

Otro punto muy importante a tener en cuenta: la computadora Servidor jamás debe tener conexión directa a Internet porque eso solamente puede producir problemas y ningún beneficio. Por lo tanto, si se necesita acceder a Internet debe hacerse por medio de otra computadora, nunca por medio de la computadora donde se encuentra el Servidor del Firebird.

Artículos relacionados:

Mejorando el rendimiento de las bases de datos (1)

El índice del blog Firebird21

 

Mejorando el rendimiento de las bases de datos (1)

6 comentarios

Si quieres que las operaciones con tu Base de Datos sean muy rápidas entonces hay 6 aspectos fundamentales que debes considerar:

  1. Hardware
  2. Software
  3. Red
  4. Administración
  5. Diseño de la Base de Datos
  6. Programación

El hardware es todo lo relacionado a la parte física de la computadora donde se encuentra el Servidor del Firebird, la conexión de red y las computadoras clientes. Esto engloba a: cantidad de memoria RAM, cantidad de núcleos, cantidad de discos duros, tipos de discos duros, capacidad de los discos duros, tarjetas de red, router, cablerío, etc.

El software se refiere al Sistema Operativo utilizado, el cual siempre debe ser una versión Server. Por ejemplo: Windows Server, Ubuntu Server, FreeBSD, OS X Server, AIX, HP-UX. ¿Por qué? porque las versiones Server están optimizadas para trabajar como servidores de bases de datos. En cambio las versiones “normales” son para los usuarios que quieren ejecutar sus aplicaciones de Contabilidad, de Control del Stock, navegar por Internet, revisar sus e-mail, visitar su Facebook, jugar sus jueguitos, etc. Estas versiones “normales” también pueden usarse como servidores de bases de datos pero no les pidas velocidad porque no están pensadas para eso.

La red está íntimamente relacionada con el hardware y con la administración. Por un lado, debes instalar tarjetas lo más rápidas posibles, jamás usar tarjetas inalámbricas porque degradan la velocidad, tener un router de buena calidad (olvídate totalmente de esos chinitos que cuestan casi lo mismo que una docena de caramelos), usar el cablerío adecuado, asegurarte que la distancia siempre sea al menos un 20% menor a la especificada (por ejemplo 1000BASE-T tiene un alcance de unos 100 metros, no uses más de 80), y por el otro lado asegurarte que la red se use exclusivamente para comunicarse con las bases de datos y para nada más. Si permites que la red la usen también con Internet y los muchachos se dedican a descargar canciones, vídeos y películas, pues no habrá red que te aguante.

La administración se divide en dos partes: una, la correspondiente al Firebird; otra, la correspondiente a las bases de datos. En la correspondiente a Firebird: ¿qué arquitectura estás usando: SuperServer, Classic, SuperClassic? ¿Cuántos núcleos están configurados? ¿en cuál disco guardas los archivos temporales? ¿en cuál disco haces el shadow?. En la correspondiente a la Base de Datos: ¿cuál es el tamaño del caché? ¿cuál es el tamaño de la página? ¿qué valor tienen la OAT y la NT? ¿cuáles son las estadísticas de los índices? ¿cuántos usuarios concurrentes tienes como máximo? ¿el sweep es manual o automático? ¿cada cuánto tiempo se hace un backup con GBAK? ¿hay transacciones que demoran mucho tiempo, cuál es el programa culpable?, etc.

El diseño de la Base de Datos es fundamental para conseguir buenos rendimientos. Aquí deberías preguntarte: ¿están todas las tablas normalizadas? ¿todas las tablas tienen las restricciones que deberían tener? ¿faltan índices para hacer las consultas más rápidas? ¿sobran índices, pues hay algunos que casi nunca se usan? ¿se pueden cambiar las estructuras de algunas tablas para conseguir mayores velocidades en las operaciones? ¿faltaría algún trigger?, etc.

En relación a la programación debes preguntarte: ¿todas las transacciones finalizan con un COMMIT o con un ROLLBACK? ¿están todas las consultas optimizadas?  ¿Hay momentos en los cuáles se realizan inserciones masivas de datos? ¿se pueden hacer transacciones más cortas?, ¿se puede reemplazar un stored procedure por otro más rápido?, ¿se puede reemplazar una vista por otra más rápida (quizás usando tablas temporales, tablas CTE, etc.)?, ¿se puede mejorar la velocidad de las inserciones masivas de datos?, etc.

Conclusión:

Como puedes ver, conseguir un rendimiento óptimo de las bases de datos no es sencillo porque involucra a muchos aspectos diferentes. Si mejoras cualquiera de ellos entonces verás un aumento en las velocidades pero para llegar al máximo debes mejorarlos a todos. Claro, eso tomará tiempo y dinero así que debes evaluar si vale la pena hacer el trabajo de optimización.

Artículos relacionados:

¿Cuál Sistema Operativo usar en el Servidor?

Consejos para optimizar el rendimiento de las bases de datos

Consultas lentas, causas y soluciones

El índice del blog Firebird21

Entendiendo “forced writes”

2 comentarios

Las palabras inglesas “forced writes” significan: escrituras forzadas, o sea escrituras obligatorias, que se escriben sí o sí.

Forced writes puede tener dos valores ON (también llamado sync) o OFF (también llamado async).

Las operaciones de escritura en Firebird son las siguientes: INSERT, UPDATE, DELETE

Cualquiera de esas tres operaciones (realizada en forma exitosa, desde luego) cambia el contenido de una tabla (agregándole filas, actualizando filas, o borrando filas) y por lo tanto también cambia el contenido de la Base de Datos.

¿Y para qué se usa “forced writes”?

Si el valor está en ON entonces inmediatamente al ejecutar un COMMIT exitoso la operación se escribe en el disco duro y la Base de Datos queda correctamente actualizada.

Si el valor está en OFF entonces al ejecutar un COMMIT exitoso los datos se guardan en una memoria caché, o sea en una porción de la memoria RAM. No se guardan en el disco duro sino en la memoria RAM y más adelante cuando el caché se llena o cuando se detiene el Servidor del Firebird son escritos en el disco duro, por lo tanto pueden estar mucho tiempo (incluso días) en la memoria RAM.

Ventajas y desventajas de usar ON u OFF

Cuando “forced writes” está en ON los datos se guardan en el disco duro y por lo tanto ya están bien seguros ahí. Pero escribir los datos en el disco duro es mucho más lento que escribirlos en la memoria RAM.

Entonces, si lo que buscamos es velocidad, que “forced writes” esté en OFF es lo mejor, sobre todo si los datos que se escriben son muchos.

Pero escribirlos en RAM tiene un gran problema potencial y es que si se corta la energía eléctrica todo el contenido de la RAM desaparece, se volatiliza, y se pierde completamente. Como la Base de Datos creía que esos datos ya estaban guardados en ella siendo que no era así porque estaban en un caché en RAM eso puede provocar corrupción en ella, es decir podría corromperse la Base de Datos con todos los grandes dolores de cabeza que tal hecho provocará.

Inclusive tener una UPS (energía de potencia ininterrumpida) no nos otorga una seguridad del 100% porque el aparatejo podría estar fallando. O podría descomponerse y quedarse sin carga en un momento en que nadie está cerca para detectarlo (por ejemplo, durante un fin de semana).

Resumiendo:

Con “forced writes” en ON se gana en SEGURIDAD, porque todos los datos se escriben sí o sí en la Base de Datos y ésta no puede corromperse.

Con “forced writes” en OFF se gana en VELOCIDAD, porque los datos se escriben en la memoria RAM que es muchísimo más rápido que escribirlos en el disco duro pero existe el riesgo de que un corte en la energía eléctrica (o un fallo en el hardware del Servidor) haga que se pierda todo lo que estaba en la memoria RAM y que además se corrompa la Base de Datos. Este problema es mucho mayor en Windows que en Linux porque el Windows es muy perezozo para escribir lo que está en la memoria caché en el disco duro, inclusive pueden pasar varios días hasta que lo haga (desde luego se supone que no se apagó la computadora en todo ese tiempo).

Recomendación:

Para el trabajo del día a día, para lo que los usuarios hacen normalmente, dejar “forced writes” en ON, con muchísima mayor razón si el Sistema Operativo de la computadora donde está instalado el Servidor es un Windows.

Para tareas esporádicas de ingreso masivo de datos (por ejemplo, para migrar todo el contenido de tablas .DBF en tablas de Firebird) poner “forced writes” en OFF y apenas la migración terminó exitosamente volver a colocar “forced writes” en ON. De esta manera conseguiremos que la velocidad de la migración sea rapidísima.

Para ver el valor actual de “forced writes”

Si quieres conocer cual valor de “forced writes” tiene actualmente una Base de Datos entonces puedes ejecutar el programa GSTAT con el parámetro -h, como se ve a continuación:

FORCED1

Captura 1. Si haces clic en la imagen la verás más grande

La flecha (1) te muestra el alias de la Base de Datos, mientras que la flecha (2) te indica que esta Base de Datos tiene “forced writes” en ON (o sea, habilitado), en otras palabras, que todas las operaciones de escritura se escribirán inmediatamente y sin esperas en el disco duro apenas finalice la transacción con un COMMIT exitoso.

Cambiando el valor de “forced writes”

Para cambiar el valor de “forced writes” debemos abrir una ventanita “símbolo del sistema”, ubicarnos en la carpeta \BIN de nuestra instalación del Firebird y escribir:

Para ponerlo en ON:

GFIX -write sync -user SYSDBA -password masterkey

Para ponerlo en OFF:

GFIX -write async -user SYSDBA -password masterkey

FORCED2

Captura 2. Si haces clic en la imagen la verás más grande

Como la flecha te indica aquí lo que se quiere es poner “forced writes” en ON (es decir: en sync), o sea que las operaciones de escritura se ejecuten inmediatamente. Eso es lo correcto durante el uso normal de la Base de Datos, y con mayor razón en Windows. Solamente durante muy cortos períodos de tiempo (por ejemplo mientras se están insertando masivamente datos) debería estar en OFF (es decir: en async).

Artículo relacionado:

El índice del blog Firebird21

 

Averiguando si un año es bisiesto

Deja un comentario

En muchas circunstancias cuando trabajamos con fechas necesitamos determinar si un año es bisiesto o no lo es.

¿Qué es un año bisiesto?

Un año es el tiempo que tarda la Tierra en dar una vuelta completa alrededor del Sol. Ese tiempo es de 365 días, 5 horas, 48 minutos, 57 segundos.

Los años “normales” tienen 365 días, pero esas 5 horas, 48 minutos, 57 segundos, se van acumulando y al cabo de 4 años tenemos que suman 23 horas, 15 minutos, 36 segundos. No alcanzan a las 24 horas que tiene un día completo pero está muy cerca, por eso cada 4 años se agrega un día. Como el mes que tiene menos días es Febrero entonces ese día adicional se agrega a Febrero el cual pasa a tener 29 días y al año se lo denomina “bisiesto”.

Pero esos 44 minutos, 14 segundos que faltaban para tener un día de 24 horas se van acumulando y al cabo de 400 años tendremos 3,07176 días de más. Se podrían restar eso 3 días sobrantes pero eso nos complicaría la vida a todos. Si nos dicen que hoy es 5 de febrero y mañana será 2 de febrero eso nos hará la vida más difícil. ¿Entonces, hay una mejor solución? Pues sí, y es la siguiente: como cada 400 años hay 3 días adicionales, los años que terminan en 00 y cuyos dos primeros dígitos no son divisibles por 4 no serán bisiestos. Esto implica que cada 400 años habrá 97 años bisiestos, no 100 años bisiestos (que sería el caso si la Tierra girara alrededor del Sol en exactamente 365 días y 6 horas). Así que en lugar de estar restando días lo que se hace es no sumarlos cuando el año termina en 00 y los dos primeros dígitos no son divisibles por 4.

Por lo tanto, para que un año sea bisiesto se deben dar 2 condiciones:

  1.  Que sea divisible por 4
  2. Si termina en 00 que sus dos primeros dígitos también sean divisibles por 4. O en otras palabras, que sea divisible por 400.

Esto implica que los años 1700, 1800, 1900, 2100, 2200, 2300 no son bisiestos (porque no son divisibles por 400). Los años 1600, 2000, 2400, sí son bisiestos (porque son divisibles por 400).

¿Y aquí termina todo?

Pues no, como la Tierra se toma el tiempo que ella quiere en girar alrededor del Sol y no el tiempo que nos gustaría a los seres humanos entonces esos 0,07176 días se van acumulando y cada 5763 años forman un día más. Pero como ninguno de nosotros estaremos vivos dentro de 5000 años dejemos a los tipos que vivan en esa época preocuparse por sus años bisiestos, que nosotros ya tenemos bastante con los nuestros.

Un stored procedure para determinar si un año es bisiesto

CREATE PROCEDURE ES_BISIESTO(
   tnAno       SMALLINT)
RETURNS(
   ftcBisiesto CHAR(1))
AS
BEGIN

   ftcBisiesto = 'F';

   IF ((MOD(tnAno, 4) = 0 AND MOD(tnAno, 100) <> 0) OR MOD(tnAno, 400) = 0) THEN
      ftcBisiesto = 'T';

END;

Como puedes ver el stored procedure es muy simple. Devuelve ‘F’ si el año no es bisiesto o devuelve ‘T’ si el año sí es bisiesto.

La función MOD() devuelve el resto de una división entera. Si el resto es 0 eso significa que la división es exacta. Si el resto es distinto de 0 eso significa que la división no es exacta.

MOD(7, 2) es 1. ¿Por qué? porque 7 dividido 2 es 3 y el resto es 1. La función MOD() nos devuelve ese resto.

MOD(8, 2) es 0. ¿Por qué? porque 8 dividido 2 es 4 y el resto es 0. Por lo tanto MOD() nos devuelve 0.

Como se trata de un stored procedure ejecutable, para ejecutarlo debes escribir:

EXECUTE PROCEDURE ES_BISIESTO(2014)

Por supuesto que en tu caso reemplazarás al año 2014 por el año que te interesa saber si es bisiesto o no lo es.

Artículos relacionados:

MOD()

El índice del blog Firebird21

http://es.wikipedia.org/wiki/A%C3%B1o_bisiesto

Usando la tabla RDB$DATABASE para mostrar resultados

2 comentarios

En SQL si quieres ver el resultado de alguna operación debes escribir un SELECT. En los lenguajes de programación esto no es así, pero en SQL sí.

En un lenguaje de programación si quieres obtener el resultado de 15 * 4 + 5 podrías escribir algo como:

? 15 * 4 + 5

PRINT 15 * 4 + 5

printf("%d", 15 * 4 + 5)

o algo similar, pero en SQL debes escribir:

SELECT 15 * 4 + 5 FROM MiTabla

En muchos ejemplos de este blog y de otros documentos o páginas web sobre Firebird verás que se usa la tabla RDB$DATABASE en el lugar de “MiTabla”.

¿Por qué?

Porque para obtener el resultado se necesita una tabla que tenga una fila, solamente una fila, y nunca ni más ni menos de una fila. O sea: que tenga exactamente una fila.

Puedes usar cualquier tabla que tenga una fila pero quien escribe los ejemplos no puede saber como se llama tu tabla que tiene una sola fila. Alguien podría tener una tabla que se llama CONTROL y tiene una sola fila. Otra persona podría tener una tabla que se llama PARAMETROS y tiene una sola fila. Otra persona podría tener una tabla que se llama EMPRESA y tiene una sola fila. Pero quien escribe los ejemplos en un blog, una página web, o un documento, no puede saberlo.

Todas las bases de datos de Firebird tienen unas tablas internas que son creadas en el preciso momento en que se crea la Base de Datos. Los nombres de esas tablas empiezan con los caracteres RDB$ o MON$. Sí o sí tu Base de Datos de Firebird tiene tablas internas cuyos nombres empiezan con RDB$ o con MON$ (por ejemplo: RDB$BACKUP_HISTORY, RDB$CHARACTER_SETS, RDB$DEPENDENCIES, MON$ATTACHMENTS, etc.)

Una de esas tablas está garantizado que siempre tendrá exactamente una fila, ni más ni menos filas. Y esa tabla se llama RDB$DATABASE.

¿Y es obligatorio que la tabla de los ejemplos tenga una sola fila?

En realidad no, pero los resultados devueltos se mostrarán en tantas filas como filas tenga la tabla utilizada. Por ejemplo, si nuestra tabla se llama BANCOS y tiene 16 filas, al escribir algo como:

SELECT 15 * 4 + 5 FROM BANCOS

esto será lo que obtendremos:

RDB

Captura 1. Si haces clic en la imagen la verás más grande

El resultado es correcto, pero como la tabla tiene 16 filas entonces lo vemos repetido 16 veces. Algo que evidentemente es innecesario, solamente necesitamos verlo una vez, no 16 veces.

Por lo tanto, lo mejor es escribir el ejemplo anterior así:

SELECT 15 * 4 + 5 FROM RDB$DATABASE

Y este será el resultado que obtendremos:

RDB2

Captura 2. Si haces clic en la imagen la verás más grande

Está muchísimo mejor, ¿verdad?

Por supuesto que si tú tienes una tabla que se llama CONTROL y estás segurísimo de que tiene exactamente una fila también podrías escribir:

SELECT 15 * 4 + 5 FROM CONTROL

Y obtendrás el mismísimo resultado que si hubieras usado la tabla RDB$DATABASE. Pero como quienes escribimos los ejemplos no sabemos como se llama tu tabla que tiene una sola fila entonces usamos la tabla RDB$DATABASE la cual sí sabemos con certeza que tiene exactamente una fila.

Así que, si no lo sabías, ahora ya sabes por qué se usa la tabla RDB$DATABASE en muchos de los ejemplos escritos sobre Firebird.

Artículo relacionado:

El índice del blog Firebird21

Older Entries