EMS SQL Manager ha sido actualizado para Firebird 3

5 comentarios

El programa administrador de bases de datos EMS SQL Manager desde el 9 de noviembre de 2016 ya ofrece soporte para las características y mejoras que fueron introducidas con Firebird 3.

ems01

Esto facilitará la migración de las bases de datos a Firebird 3 a aquellos que están acostumbrados a trabajar con este administrador gráfico.

Artículos relacionados:

El índice del blogFirebird21

El foro del blog Firebird21

 

Anuncios

Trabajando con grandes bases de datos

4 comentarios

Los problemas con los cuales nos encontramos al trabajar con bases de datos grandes son distintos a los problemas que tienen las bases de datos pequeñas.

Como las empresas constantemente están almacenando más y más datos las tablas van creciendo de tamaño diariamente, quizás minuto a minuto. Llega un momento en que la Base de Datos ya puede considerarse “grande”.

¿Cuándo una Base de Datos es grande?

Como muchas otras cosas en Informática, ésta también depende del punto de vista. Para alguien podría ser grande y para otros pequeña, aunque en general se considera “grande” a las bases de datos que alcanzan o superan un tamaño de 10 Gigabytes. En este blog se considera que:

  • Pequeña. Es una Base de Datos con tamaño menor a 1 Gb
  • Mediana. Es una Base de Datos cuyo tamaño está entre 1 Gb y 10 Gb
  • Grande. Es una Base de Datos cuyo tamaño es mayor que 10 Gb

Normalmente, si no se almacena multimedia (archivos gráficos, de sonido, de vídeo, etc.) las bases de datos van creciendo a un ritmo bastante parejo y predecible, por ejemplo podríamos tener una que crece alrededor de 1 Megabyte por día. Desde luego que algunos días crece más y algunos días crece menos, pero siempre está por ahí cerca.

Problemas típicos con las bases de datos pequeñas

  • Consultas lentas
  • Stored procedures o triggers lentos

Soluciones típicas a esos problemas

  • Optimizar las instrucciones SQL.
  • Realizar un ciclo backup/restore con el programa GBAK

El optimizar las instrucciones SQL (principalmente las cuatro principales: INSERT, UPDATE, DELETE, SELECT) conduce a una notoria mejoría en la velocidad. Muy relacionado con esto se encuentra el correcto manejo de las transacciones. Ante alguna corrupción restaurar el backup realizado con GBAK suele ser suficiente.

Problemas típicos con las bases de datos grandes

  • No se sabe donde está el problema
  • No se sabe por qué sucede
  • Realizar un ciclo backup/restore puede ser una gran pérdida de tiempo, porque la restauración puede demorarse un día o más, y no asegura que se haya solucionado el problema

Tareas administrativas diarias en las bases de datos grandes

Si ocurre un problema, puede demorarse mucho la solución así que lo más inteligente es evitar que ocurra. Para ello:

  1. Debe realizarse un backup con GBAK todos los días
  2. Debe verificarse el rendimiento de todas las transacciones
  3. Debe verificarse que todas las instrucciones SQL estén optimizadas
  4. Debe verificarse cada índice y la estadística de cada índice
  5. Debe verificarse que la estructura de la Base de Datos sea la más conveniente
  6. Debe verificarse el archivo FIREBIRD.LOG varias veces por día

Aunque realizar un ciclo backup/restore no nos asegura que solucionaremos todos los problemas, tener una Base de Datos grande sin backups actualizados es un suicidio. En las transacciones lo más importante es que ninguna demore mucho en completarse (“mucho” es relativo, pero en general si tarda más de un minuto entonces está tardando una eternidad). Las instrucciones SQL no optimizadas hacen perder tiempo, algo que no se puede permitir en estas circunstancias. Y no debemos olvidar que una instrucción SQL que hoy está optimizada y funciona perfectamente podría dejar de estarlo dentro de unos meses cuando la Base de Datos haya aumentado mucho de tamaño. Por eso la verificación debe hacerse diariamente.

El archivo FIREBIRD.LOG es el mejor lugar para verificar que todo esté correcto, si hay algún problema casi siempre aparecerá en ese archivo.

¿Cómo realizar el ciclo backup/restore?

Es bastante frecuente, aunque erróneo, hacerlo de esta manera:

Base de Datos —> Backup con el mismo nombre anterior

Por ejemplo, la Base de Datos se llama CONTA.FDB y el archivo de backup siempre se llama CONTA.FBK, ¿cuál es el problema potencial? Que si la Base de Datos está corrupta entonces el nuevo backup no servirá y el anterior no podrá ser utilizado porque fue sobre-escrito.

Lo correcto, por lo tanto, es hacer el backup de esta manera:

Base de Datos —> Backup con un nombre distinto al anterior

Esto evidentemente implica que tendremos varios archivos de backup, pero es preferible que sobren y no que falten.

El archivo delta

Cuando se ejecuta el programa GBAK para realizar un backup, éste hace el backup de todo el contenido que tiene en ese momento la Base de Datos. Es como si le tomara una fotografía. Nada que se realice con posterioridad se guardará en el backup ni en la Base de Datos, sólo lo que existía en el momento de iniciarse GBAK. Pero ¿y qué pasa con los datos que los usuarios continúan insertando, actualizando o borrando? Que no se guardan en la Base de Datos original sino en un archivo temporario llamado delta. Cuando GBAK finaliza, entonces todo el contenido del archivo delta se copia dentro de la Base de Datos.

Cuando hacemos backup de bases de datos pequeñas no vale la pena preocuparse por ese archivo delta pero cuando es una Base de Datos grande sí, porque no podemos permitirnos que esté corrupto. Un motivo podría ser que no haya suficiente espacio en el disco duro para el archivo delta.

La restauración

Aquí, es obligatorio que al finalizar un backup se realice un restore (en otro disco duro y preferiblemente en otra computadora) para asegurarnos de que se encuentre en perfectas condiciones y pueda ser utilizado en caso de necesidad.

Nada hay peor que creer que se tiene un backup actualizado pero eso no es cierto porque el backup se encuentra inservible. No ocurre frecuentemente, pero a veces ocurre, y no se puede tomar ese riesgo.

Los índices

Los índices en Firebird se utilizan en las búsquedas y en los filtros (cláusula WHERE) y cuando deseamos que los resultados aparezcan en un cierto orden (cláusula ORDER BY)

Para saber si un índice es el adecuado, es necesario, y se encuentra en buena salud, debemos verificar sus estadísticas. En Firebird los índices pueden degradarse y no debemos permitir que tal cosa ocurra.

Acciones a tomar si se descubre un problema

Estas son recomendaciones que a veces podrían no aplicarse, dependen de cada caso, pero servirán de guía:

  1. Una transacción está demorando mucho. Detectar cual es la transacción, cual es el programa culpable, y desconectar al usuario
  2. Una consulta está demorando mucho. Verificar cual es la consulta, mirar su PLAN y si es necesario crear un nuevo índice

Programas que se pueden utilizar cuando se trabaja con grandes bases de datos

Aunque detectar los problemas y solucionarlos podría hacerse manualmente, eso requerirá que la persona encargada conozca mucho del tema y que tenga suficiente tiempo y ganas para dedicarle a esa tarea. Para estos casos se justifica adquirir software que ayude en la detección y corrección. Los recomendados son:

  • FBDataGuard. Se ejecuta en la misma computadora donde se encuentra la Base de Datos. Su principal tarea es prevenir que se corrompa. Monitorea el rendimiento, realiza el backup en la forma correcta, obtiene estadísticas, y si descubre algún problema entonces envía un e-mail describiéndolo
  • FBScanner. Verifica cada instrucción SQL que el Cliente le envía al Servidor, puede realizar un análisis detallado de cada consulta, PLAN, transacción y conexión, de esta manera sirve para detectar los “cuellos de botella”, las transacciones que se demoran mucho, los usuarios que se desconectan de mala manera, y monitorea lo que un usuario o una aplicación están realizando.
  • IBTM. Monitorea y analiza transacciones dinámicas. Obtiene los valores de OIT, OAT, OST, NT y visualiza como se van moviendo. Detecta transacciones que se demoran mucho, los momentos en que muchas transacciones se están ejecutando, los momentos en que ocurre el sweep, la basura dejada por los ROLLBACKs.
  • IBAnalyst. Analiza las estadísticas de la Base de Datos e identifica posibles problemas que causan un bajo rendimiento: transacciones que demoran mucho, cantidad de versiones de los registros, registros que han sido borrados pero aún permanecen en la Base de Datos y por lo tanto demoran la lectura, promedio de transacciones por día, conexiones perdidas, índices no usados, índices con muchos valores repetidos, etc.
  • FBMonLogger. Detecta consultas lentas, transacciones que tienen un aislamiento incorrecto, basura que debe ser recolectada, uso de la memoria, etc.
  • Sinática. Monitorea a la Base de Datos en tiempo real, ayudando a detectar los procesos que consumen muchos recursos o que producen “cuellos de botella”, además de las transacciones que demoran mucho en finalizar.

Conclusión:

Aunque realizar las tareas administrativas de backup, verificación de las estadísticas de los índices, revisar el archivo FIREBIRD.LOG, etc. deberían hacerse regularmente con cualquier Base de Datos, cuando éstas son de gran tamaño esas tareas ya son una obligación imprescindible porque no se puede correr el riesgo de que se corrompa o de que funcione muy lentamente, muchas veces tales bases de datos deben funcionar 365/24/7 (o sea, los 365 días del año, durante las 24 horas, de cada uno de los 7 días de la semana) y cualquier demora o detención puede ser muy grave.

En estos casos, suele ser recomendable contratar a una persona cuya función sea la de Administrador de la Base de Datos y proveerle de las herramientas informáticas adecuadas para que pueda realizar efectivamente su labor.

Artículos relacionados:

El índice del blog Firebird

El foro del blog Firebird21

Artículos

Algunas preguntas y respuestas sobre el SQL de Firebird

7 comentarios

1. ¿Cómo creo una nueva Base de Datos?

Usando el comando CREATE DATABASE

2. ¿Cómo creo una tabla?

Usando el comando CREATE TABLE

3. ¿Qué es un dominio?

Un tipo de datos que yo puedo definir, usando para ello un tipo de datos ya existente

4. ¿Cómo le agrego datos a una tabla?

Con el comando INSERT o con el comando UPDATE OR INSERT

5. ¿Cómo modifico los datos de una tabla?

Con el comando UPDATE o con el comando UPDATE OR INSERT

6. ¿Cómo borro filas de una tabla?

Con el comando DELETE

7. ¿Cómo puedo conocer el contenido de una tabla?

Con el comando SELECT

8. ¿Cómo puedo combinar datos de dos o más tablas?

Con las cláusulas JOIN y UNION

9. ¿Una tabla puede combinarse con sí misma?

10. ¿Cómo puedo mostrar los resultados de un SELECT ordenados?

Con la cláusula ORDER BY

11. ¿Qué debo hacer para buscar un dato dentro de una tabla?

Usar la cláusula WHERE o la cláusula HAVING

12. ¿Cómo puedo totalizar los valores de una columna de una tabla?

Usando la función agregada SUM().

 13. ¿Cómo hago para agrupar datos similares?

Usando la cláusula GROUP BY

14. ¿Qué es una clave primaria o Primary Key?

Un valor único que sirve para identificar a cada fila de una tabla, las Primary Key no pueden repetirse ni tener valores NULL

15. ¿Qué es un valor NULL?

Un valor desconocido. NULL no es lo mismo que una cadena vacía ni una fecha vacía ni un cero. NULL significa “desconocido” o sea que no se tiene la menor idea de cual es su valor.

16. ¿Qué es una clave foránea o Foreign Key?

Un valor que sirve para relacionar a dos tablas entre sí.

17. ¿Qué es una clave única o Unique Key?

Un valor que no puede estar repetido.

18. ¿Qué es una restricción check?

Una condición que debe cumplirse para que una fila pueda ser insertada o actualizada

19. ¿Qué es un stored procedure?

Una rutina que se ejecuta cuando el desarrollador de la Base de Datos quiere que se ejecute

20. ¿Qué es un trigger?

Una rutina que se ejecuta automáticamente cuando se cumple una condición

21. ¿Cómo puedo restringir el acceso al contenido de la Base de Datos?

Otorgándoles derechos, también llamados permisos o privilegios, a las personas autorizadas. Si muchas personas compartirán los mismos derechos entonces suele ser conveniente crear roles. Un rol es un grupo de usuarios que tienen exactamente los mismos derechos.

Artículos relacionados

El índice del blog Firebird21

El foro del blog Firebird21

 

Entendiendo a los JOIN

3 comentarios

En SQL hay dos formas de relacionar tablas entre sí:

  1. Con la cláusula FROM
  2. Con la cláusula JOIN

Cuando se las relaciona mediante la cláusula FROM se escribe algo como:

SELECT
   Columna1,
   Columna2,
   ColumnaN
FROM
   Tabla1,
   Tabla2
WHERE
   Condición_entre_Tabla1_y_Tabla2

En cambio, cuando se las relaciona mediante la cláusula JOIN se escribe algo como:

SELECT
   Columna1,
   Columna2,
   ColumnaN
FROM
   Tabla1
JOIN
   Tabla2
   ON Condición_entre_Tabla1_y_Tabla2

La primera forma (la que utiliza FROM) es la forma antigua de relacionar dos tablas entre sí. Está basada en el cálculo.

La segunda forma (la que utiliza JOIN) es la forma moderna de relacionar dos tablas entre sí. Está basada en el álgebra.

NOTA: Quizás no sabías que el lenguaje SQL está basado en tres ramas de la Matemática: el cálculo integral, el álgebra y la teoría de conjuntos.

Un JOIN es el producto cartesiano entre las dos tablas involucradas. Eso significa que el resultado de un JOIN combina cada fila de la primera tabla con cada fila de la segunda tabla.

Por ejemplo, si la primera tabla tiene 3 filas y la segunda tabla tiene 7 filas al hacer un JOIN el resultado tendrá 21 filas (que es lo que se obtiene al multiplicar 3 por 7)

En tablas compuestas por miles o por millones de filas, la cantidad de filas del resultado puede ser asombrosamente grande; por ese motivo es que siempre debemos acotar lo más posible a los JOIN. En otras palabras, ponerles la mayor cantidad de condiciones para que obtengamos un resultado manejable.

Ejemplo:

Nuestra tabla de SUCURSALES tiene estas filas:

JOIN1

Captura 1. Tabla de SUCURSALES (si haces clic en la captura la verás más grande)

Y nuestra tabla de BANCOS tiene estas filas:

JOIN2

Captura 2. Tabla de BANCOS (si haces clic en la captura la verás más grande)

Listado 1. Viendo el producto cartesiano de la tabla SUCURSALES por la tabla BANCOS

SELECT
   B.*,
   S.*
FROM
   BANCOS     B
JOIN
   SUCURSALES S
      ON B.BAN_IDENTI > 0

JOIN3

Captura 3. Resultado del JOIN entre BANCOS y SUCURSALES (si haces clic en la captura la verás más grande)

 Como puedes ver, cada Banco se ha combinado con cada Sucursal. Eso ocurrió porque nuestra condición (B.BAN_IDENTI > 0) es siempre verdadera e involucra a solamente una de las tablas. Podemos también ver la cantidad de lecturas ocurridas en cada tabla haciendo clic en la pestaña “Performance Analysis” del EMS SQL Manager y esto será lo que obtendremos:

JOIN4

Captura 4. Performance Analysis del JOIN entre BANCOS y SUCURSALES (si haces clic en la captura la verás más grande)

 Acotemos ahora el JOIN para volverlo más manejable.

Listado 2. Viendo el producto cartesiano de la tabla SUCURSALES por la tabla BANCOS relacionando ambas tablas.

SELECT
   B.*,
   S.*
FROM
   BANCOS     B
JOIN
   SUCURSALES S
   ON B.BAN_CODSUC = S.SUC_CODIGO

Como ahora tenemos una condición que relaciona a ambas tablas entre sí (mediante las columnas B.BAN_CODSUC y S.SUC_CODIGO) aunque el resultado sigue siendo el producto cartesiano entre ellas (es decir: todas las filas de SUCURSALES combinadas con todas las filas de BANCOS) la condición limita o acota las filas devueltas por el SELECT, quedando ahora así:

JOIN5

Captura 5. Relacionando las tablas BANCOS y SUCURSALES entre sí (si haces clic en la captura la verás más grande)

Y al hacer clic sobre “Performance Analysis” esto es lo que obtenemos:

JOIN6

Captura 6. Performance Analysis del JOIN entre BANCOS y SUCURSALES (si haces clic en la captura la verás más grande)

Si ahora le ponemos una condición usando la cláusula WHERE el conjunto resultado estará aún más limitado o acotado.

Listado 3. Un JOIN con una cláusula WHERE

SELECT
   B.*,
   S.*
FROM
   BANCOS B
JOIN
   SUCURSALES S
   ON B.BAN_CODSUC = S.SUC_CODIGO
WHERE
   B.BAN_IDENTI = 6

Al usar WHERE para poner una condición que limita la cantidad de filas devueltas obtendremos aún menos filas, como podemos ver aquí:

JOIN7

Captura 7. Usando WHERE para limitar las filas devueltas (si haces clic en la captura la verás más grande)

Y al hacer clic sobre la pestaña “Performance Analysis” esto es lo que obtenemos:

JOIN8 

Captura 8. Performance Analysis al usar WHERE para limitar las filas devueltas (si haces clic en la captura la verás más grande)

Conclusión:

Un JOIN es igual al producto cartesiano entre las filas de dos tablas. Eso significa que se combinan todas las filas de la primera tabla con todas las filas de la segunda tabla. Debido a ello en tablas que tienen miles o millones de filas el resultado de un JOIN puede estar compuesto por una cantidad asombrosamente grande de filas. Para limitar esa cantidad debemos asegurarnos que una o más columnas de la primera tabla se relacionen con una o más columnas de la segunda tabla. Además, siempre que podamos debemos usar la cláusula WHERE para limitar aún más la cantidad de filas devueltas.

En nuestro ejemplo, con el SELECT del Listado 1. el Firebird hizo 24 lecturas (21 en BANCOS y 3 en SUCURSALES). Con el SELECT del Listado 2. el Firebird hizo 14 lecturas (7 en BANCOS y 7 en SUCURSALES). Con el SELECT del Listado 3. el Firebird hizo 4 lecturas (1 en BANCOS y 3 en SUCURSALES). Al ir poniendo condiciones conseguimos bajar la cantidad inicial de lecturas (24) a solamente 4.

Menos lecturas implica mucha mayor velocidad de respuesta.

Artículo relacionado:

El índice del blog Firebird21

¿Por qué este blog?

6 comentarios

Hay mucha información sobre Firebird SQL en otros idiomas (inglés, portugués, ruso, etc.) pero relativamente poca en castellano. Por eso, decidí crear un blog donde se pueda encontrar información útil.

Aunque tocaré aspectos teóricos, mi intención principal es que ayude a resolver problemas prácticos, los que podemos encontrarnos en el día a día.

La versión de Firebird que yo normalmente uso es la 2.5.1 así que todos los ejemplos han sido verificados con esa versión, si tú usas una versión anterior quizás algunas cosas no te funcionen o sean distintas.

Actualización del día 10 de marzo de 2014: Desde hace varios meses ya que utilizo la versión 2.5.2, así que todos los ejemplos están comprobados que funcionan con esa versión. No puedo asegurar que también funcionen con versiones anteriores porque no los pruebo con versiones anteriores. Si descubres alguno que no funciona te agradeceré que me lo hagas saber.