Optimizando SuperServer: poniendo toda la Base de Datos en la memoria caché

5 comentarios

Hay un truco que podemos utilizar para optimizar a SuperServer, funciona también en Classic pero solamente con bases de datos mucho más pequeñas.

Como recordarás, si las filas que devolverá un SELECT ya se encuentran en la memoria caché entonces la velocidad de respuesta será muy alta porque la memoria RAM es muchísimo más rápida que el disco duro. Entonces, la idea es tener a toda la Base de Datos (o al menos a las tablas más utilizadas cuando tener a toda la Base de Datos no es posible) en la memoria caché.

Para poner a toda la Base de Datos en la memoria caché podríamos ejecutar el siguiente stored procedure:

Listado 1.

CREATE PROCEDURE LLENAR_CACHE
AS
   DECLARE VARIABLE lcNombreTabla   VARCHAR(1024);
   DECLARE VARIABLE lcComando       VARCHAR(1024);
   DECLARE VARIABLE lnCantidadFilas INTEGER;
BEGIN
   
   FOR SELECT
      RDB$RELATION_NAME
   FROM
      RDB$RELATIONS
   INTO
      :lcNombreTabla
   DO BEGIN
      lcComando = 'SELECT COUNT(*) FROM ' || lcNombreTabla;
      EXECUTE STATEMENT lcComando INTO :lnCantidadFilas;
   END

END;

Luego de ejecutar el comando EXECUTE PROCEDURE LLENAR_CACHE y el comando COMMIT, toda la Base de Datos se encontrará en la memoria caché (si hay suficiente espacio en la memoria caché, por supuesto). ¿Por qué? Porque cada vez que se lee una página de una tabla esa página es puesta en la memoria caché. La función COUNT(*) lee cada página de una tabla y por consiguiente coloca a cada página de esa tabla en la memoria caché. El stored procedure LLENAR_CACHE realiza esa operación para todas las tablas de la Base de Datos. Como resultado final, todas las páginas de todas las tablas se encontrarán en la memoria caché, si es que hay allí suficiente espacio libre.

¿Y si no hay suficiente espacio libre?

Entonces podríamos poner en la memoria caché a las tablas más utilizadas en los informes.

Listado 2.

CREATE PROCEDURE LLENAR_CACHE
AS
BEGIN
   SELECT COUNT(*) FROM BANCOS;
   SELECT COUNT(*) FROM PRODUCTOS;
   SELECT COUNT(*) FROM CLIENTES;
   SELECT COUNT(*) FROM PROVEEDORES;
   SELECT COUNT(*) FROM STOCK;
   SELECT COUNT(*) FROM MONEDAS;
END; 

Eso hará que todas las operaciones de lectura se realicen súper rápido. Pero durante el trabajo normal diario muchas operaciones de INSERT, UPDATE, y DELETE se irán ejecutando y en la memoria caché ya no se encontrarán las últimas filas insertadas, actualizadas, y borradas.

¿Y entonces?

Entonces lo que debemos hacer es volver a ejecutar el stored procedure LLENAR_CACHE para que nuevamente en la memoria caché se encuentre toda la Base de Datos (como en el caso del Listado 1.) o las tablas más utilizadas (como en el caso del Listado 2.).

Ese proceso podríamos hacerlo manualmente (por ejemplo, cada hora) pero es mucho más inteligente pedirle al Sistema Operativo que realice esa tarea.

Para ello crearemos un archivo de script y un archivo batch.

Listado 3.

CONNECT MiBaseDatos.FDB USER SYSDBA PASSWORD masterkey;

-- Primera vez
EXECUTE PROCEDURE LLENAR_CACHE;
COMMIT;
SHELL PING 192.0.2.2 -n 1 -w 36000 > NUL;

-- Segunda vez
EXECUTE PROCEDURE LLENAR_CACHE;
COMMIT;
SHELL PING 192.0.2.2 -n 1 -w 5000 > NUL;

-- Finalizar
EXIT;

Escribimos el contenido del Listado 3. en el bloc de notas y lo grabamos con el nombre LLENAR_CACHE.SQL

¿Qué hace este archivo de script?

Primero, se conecta a nuestra Base de Datos. Segundo, ejecuta el stored procedure llamado LLENAR_CACHE. Tercero, para finalizar la transacción hace un COMMIT. Cuarto, ejecuta el comando PING del Sistema Operativo donde la dirección IP mostrada es una IP que nunca existe y se usa normalmente para pruebas, la opción -n indica la cantidad de repeticiones, la opción -w indica la cantidad de milisegundos (36.000 milisegundos = 1 hora), y al redirigir a NUL no se ve salida en la pantalla.

En el Listado 3. el stored procedure LLENAR_CACHE se ejecutó 2 veces, con una hora de diferencia entre esas ejecuciones. Si la Base de Datos se usará durante 10 horas seguidas cada día, entonces deberíamos escribir 10 veces el EXECUTE PROCEDURE, el COMMIT, y el SHELL. Para que el Listado 3. no sea muy largo solamente escribí 2 veces esos comandos, en tu caso podrías necesitar escribirlos 8 veces, 10 veces, 14 veces, etc.

Listado 4.

C:
CD "\ARCHIVOS DE PROGRAMA\FIREBIRD\FIREBIRD_2_5\BIN"
ISQL -INPUT C:\USERS\WALTER\DESKTOP\LLENAR_CACHE.SQL

¿Qué hace este archivo batch?

Primero, se ubica en la unidad C:. Segundo, se ubica en la carpeta donde se encuentra el programa ISQL.EXE. Tercero, ejecuta el programa ISQL.EXE con la opción -INPUT y el nombre completo del archivo de script.

En síntesis, ejecuta al programa ISQL.EXE pidiéndole que ejecute los comandos que se encuentran en el archivo de script.

¿Cómo ejecutamos ese archivo batch?

Tenemos dos formas:

  • Manualmente
  • Automáticamente

Manualmente sería haciendo clic en él cada día antes de que el primer usuario empiece a trabajar, por ejemplo a las 7:30 de cada día. El problema es que podríamos olvidarnos de hacer ese clic o llegamos tarde al trabajo o estamos de vacaciones, etc.

Automáticamente sería mediante el Programador de Tareas del Windows. Podríamos programar una tarea que se ejecute cada vez que se enciende el Servidor o cada día a las 7:30. También podríamos hacerlo en nuestra aplicación: si detectamos que nadie está usando la Base de Datos entonces ejecutamos el archivo batch.

Conclusión:

Si la arquitectura que usamos es SuperServer entonces podemos conseguir que los resultados de las consultas sean rapidísimos poniendo a toda la Base de Datos en la memoria caché. Si no tenemos suficiente memoria para poner a toda la Base de Datos en la memoria caché, entonces pondremos allí a las tablas más utilizadas.

Dependiendo de nuestro caso crearíamos un stored procedure como el mostrado en el Listado 1. o como el mostrado en el Listado 2.

Luego creamos un archivo de script como el mostrado en el Listado 3., el cual se encargará de llenar la memoria caché. Como los usuarios estarán insertando, actualizando, y borrando filas de las tablas el contenido de la memoria caché se irá quedando desactualizado. Por eso cada hora (o el tiempo que te parezca conveniente) se vuelve a llenar la memoria caché con el contenido actual de cada tabla.

Finalmente, creamos un archivo batch que se encargará de ejecutar al programa ISQL.EXE teniendo como entrada al archivo de script. Ese archivo batch debería ser ejecutado cada día antes de que el primer usuario se conecte a la Base de Datos. Esto podríamos hacerlo manualmente o mucho mejor, automáticamente.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Anuncios

Los archivos temporales del Firebird

Deja un comentario

El Firebird a veces necesita crear archivos temporales, eso generalmente ocurre cuando en un comando SELECT se usa la cláusula ORDER BY y no existe un índice que pueda ser usado, o cuando ya no hay espacio disponible en la porción de memoria RAM que utiliza para los ordenamientos, o cuando se crean tablas temporales (o sea: tablas GTT) de gran tamaño.

Si el Servidor del Firebird recibe la orden de ejecutar un SELECT que contiene la cláusula ORDER BY y no hay un índice que pueda utilizar entonces evidentemente debe ordenar esas filas en algún lado para poder mostrarlas ordenadas.

¿Dónde se realiza ese ordenamiento?

El Firebird usa una porción de la memoria RAM a la cual llama Sort Buffer para realizar en ella los ordenamientos. Sin embargo, el espacio del Sort Buffer es limitado y en ocasiones puede ser insuficiente.

¿Qué sucede cuando no hay espacio suficiente en el Sort Buffer para realizar allí el ordenamiento?

Que el Firebird crea archivos temporales. Como no dispone de memoria RAM (la cual es rapidísima) para ordenar el resultado de la consulta entonces crea en el disco duro archivos temporales. Esto es mucho más lento que usar la memoria RAM pero funciona y no hay otra alternativa: hay que crear archivos temporales sí o sí.

¿Cuáles son los nombres de esos archivos temporales?

Todos los archivos temporales creados por el Firebird empiezan con los caracteres FB_ y dependiendo de su contenido serán los siguientes caracteres, por ejemplo si empieza con:

FB_QUERY_  significa que es un archivo temporal creado porque se usó la cláusula ORDER BY sin tener un índice disponible

FB_TABLE_ significa que se creó una tabla temporal (una tabla GTT)

¿Cómo puedo especificar dónde se crearán esos archivos temporales?

Por defecto, si el Firebird es iniciado como un servicio entonces los archivos temporales son creados en la carpeta temporal del Windows, normalmente en C:\WINDOWS\TEMP\ pero si se quiere crearlos en otras carpetas hay dos formas de hacerlo:

  1. Especificando las variables de entorno FIREBIRD_TMP, TEMP, TMP
  2. Cambiando la entrada TempDirectories del archivo FIREBIRD.CONF que se encuentra en la carpeta donde instalaste el Firebird

TEMP1

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

En la Captura 1. podemos ver como especificar una carpeta donde guardar los archivos temporales del Firebird que no sea la que utiliza el Windows. Por supuesto que la carpeta especificada (en este caso: E:\FIREBIRD_ARCHIVOS_TEMPORALES) debe existir y el nombre de la carpeta puede ser cualquiera, el nombre mostrado en la Captura 1. es solamente un ejemplo.

TEMP2

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

En la Captura 2. podemos ver como especificar cual será la carpeta temporal en el archivo FIREBIRD.CONF, recordando que debemos borrar el símbolo de numeral que se encuentra a la izquierda de la entrada TempDirectories ya que el símbolo # indica que lo que sigue a continuación es un comentario.

El autor de este blog recomienda que se especifique la carpeta de los archivos temporales en la entrada TempDirectories y que de ser posible se utilice un disco RAM para ese propósito.

¿Puedo tener más de una carpeta para guardar los archivos temporales?

Sí, sin problema, lo único que debes hacer es separarlas con un punto y coma, por ejemplo:

TempDirectories=E:\FIREBIRD_TEMP;F:\ARCHIVOS_TEMP_FIREBIRD;G:\FIREBIRD_TEMP

¿Puedo especificar el tamaño de las carpetas dónde se guardarán los archivos temporales?

Sí, si lo deseas puedes especificar inclusive el tamaño en bytes que se usará en cada carpeta, por ejemplo:

TempDirectories=E:\FIREBIRD_ARCHIVOS_TEMPORALES 100000000

o

TempDirectories=E:\FIREBIRD_TEMP 250000000;F:\TEMP_FILES 300000000;G:\MIS_TEMPORALES 100000000

¿Por qué los archivos temporales del Firebird a veces tienen un tamaño muy grande?

Porque el Firebird expande las columnas CHAR y VARCHAR a su tamaño especificado en la definición de la tabla. Muchos programadores saben que el Firebird no guarda en el disco duro el tamaño especificado en la tabla sino que guarda el contenido de esas columnas comprimido. Entonces saben que pueden especificar un tamaño mucho mayor al necesario sin problema. Por ejemplo, supongamos que la mayor longitud que necesitamos en una columna es de 850 bytes pero en la definición de la tabla usamos 1.000 bytes, 4.000 bytes ó 12.500 bytes; estará todo bien, porque el Firebird nunca guardará más de 850 bytes en el disco duro, sin importar como se definió la columna. Eso en general es algo muy bueno.

Sin embargo, al hacer un SORT a esa columna la cosa cambia, porque allí sí el Firebird utiliza el tamaño usado en la definición de la columna.

De esta manera, inclusive a veces podríamos encontrarnos que tenemos un archivo temporal … cuyo tamaño es mayor al tamaño de la Base de Datos.

Así que, a no exagerar con el tamaño de las columnas CHAR y VARCHAR si existe la posibilidad de que alguna vez sean usadas en la cláusula ORDER BY de un comando SELECT.

¿Puedo borrar los archivos temporales?

Sí, si el Firebird no los está usando. El Windows no permite que se borre un archivo si algún programa lo está usando, esa es una muy buena medida de precaución.

Entonces, puedes intentar borrar cualquier archivo temporal. Si tuviste éxito eso significa que ningún programa lo estaba usando. Si no pudiste borrarlo entonces tendrás que esperar hasta que deje de ser usado.

Conclusión:

A veces el Firebird necesita crear archivos temporales en el disco duro. Nosotros podemos decirle cuales carpetas debe utilizar para eso e inclusive la cantidad de bytes que puede usar en cada carpeta.

Para aumentar la velocidad de los ordenamientos lo recomendable es usar un disco RAM, si eso no es posible entonces lo recomendable es que los archivos temporales se guarden en un disco duro distinto al usado para guardar las bases de datos.

Artículos relacionados:

Creando y usando tablas temporales

Usando un disco RAM para aumentar la velocidad

Acelerando los SORT

Configurando al Firebird

¿En cuál carpeta tener las bases de datos?

El índice del blog Firebird21

El foro del blog Firebird21

Acelerando los SORT

1 comentario

Ya sabemos que en ocasiones el Firebird necesita ordenar las filas creando archivos temporales, a esa operación se la llama SORT (ordenar, en inglés) y puede ser lenta en tablas grandes. Entonces ¿qué podemos hacer para acelerar los SORT?

  1. Pedirle que los realice en un disco rápido
  2. Pedirle que los realice en un disco RAM
  3. Asegurándonos que el espacio libre en el disco temporario sea más grande que la Base de Datos
  4. Creando los archivos temporales en un disco distinto al de la Base de Datos

Los discos tienen distintas velocidades de lectura/escritura (y distintos precios también, claro). Los más rápidos suelen ser los SSD (Solid State Disk), aunque el problema es que son más caros que los discos duros magnéticos y también tienen una menor vida útil (aunque esto último está cambiando mucho, ya que cada vez duran más tiempo).

Como los SORT requieren crear archivos temporales, y muchos de esos archivos temporales pueden llegar a ser inmensos entonces debemos buscar por todos los medios acelerar el proceso.

Usar un disco RAM es una muy buena alternativa, aunque por supuesto eso requiere que la computadora tenga mucha memoria disponible. Para saber como crear un disco RAM y que programa usar para ello, puedes leer este artículo:

Usando un disco RAM para aumentar la velocidad

 ¿Y cuánto espacio libre debe tener el disco dónde se realizarán los SORT?

Evidentemente, cuanto más, mejor. Como no podemos saber de antemano cuanto será el espacio libre que necesitará el Firebird en general se toma como parámetro el tamaño de la Base de Datos. Es casi seguro que siempre necesitará menos que eso.

Entonces, si nuestra Base de Datos tiene un tamaño de 2 Gb, con tener 2 Gb en el disco donde se crearán los archivos temporales será suficiente. Pero no olvides que las bases de datos siempre crecen entonces hay que prever más, en ese caso un disco (duro o RAM) con 4 Gb sería muy bueno.

¿Y cómo se especifica dónde se crearán los archivos temporales?

En la carpeta donde instalaste el Firebird encontrarás un archivo cuyo nombre es FIREBIRD.CONF, dentro de ese archivo hay una entrada llamada “TempDirectories”. Debes borrar el símbolo de numeral que está a la izquierda y escribir los nombres de las carpetas donde se crearán los archivos temporales. Si usarás más de una carpeta deberás separarlas con punto y coma, por ejemplo:

TempDirectories=G:\TEMP
TempDirectories=G:\TEMP;F:\FIREBIRDTEMPS

¿Qué significan esas entradas?

La primera, que todos los archivos temporales se crearán en la carpeta G:\TEMP

La segunda, que los archivos temporales se crearán en G:\TEMP y que si alguna vez no hay espacio suficiente entonces se los continuará creando en F:\FIREBIRDTEMPS

Es decir, la segunda carpeta solamente se usa si la primera carpeta se quedó sin espacio.

¿Cómo se deben especificar los nombres de las carpetas en TempDirectories?

Como el Firebird primero usará la primera carpeta, y si se queda sin espacio allí usará la segunda carpeta, entonces en primer lugar deberías escribir el nombre de la carpeta que se encuentra en el disco más rápido. Si tienes un disco RAM entonces esa primera carpeta evidentemente será la del disco RAM.

En el ejemplo de arriba si el disco G: es un disco RAM y el disco F: es un disco SSD, entonces estará perfecto, porque primero especificamos el disco más rápido.

Desde luego que puedes tener más de dos carpetas, aunque en este ejemplo se mostraron 2 carpetas tú podrías tener 3, 4, 5, las que necesites. Solamente recuerda que siempre los discos más rápidos deben ser escritos primero.

¿Por qué los discos donde se encuentran las bases de datos y los archivos temporales debe ser distinto?

Si una sola persona está usando la Base de Datos, no hay problema, porque o está creando archivos temporales o no los está creando. En ambos casos estará trabajando a la máxima velocidad posible. Pero lo normal es que a una Base de Datos estén conectadas varias personas al mismo tiempo, cada una de ellas realizando alguna operación y ahí sí el tema se complica y mucho.

¿Por qué se complica?

Tenemos dos posibilidades:

  1. Están en un disco duro magnético
  2. Están en un disco no magnético (por ejemplo, un disco SSD)

Si están en un disco duro magnético, entonces hay un cabezal que debe moverse. Ese es un movimiento mecánico y por lo tanto siempre será lento. Si un usuario hace un SORT el cabezal debe moverse a un sector del disco duro. Otro usuario hace un INSERT, el cabezal debe moverse a otro sector del disco duro. Otro usuario hace un INSERT a otra tabla y nuevamente el cabezal debe moverse. Si los usuarios están ejecutando las operaciones de INSERT, UPDATE, DELETE, SELECT, FETCH, entonces los sectores estarán contiguos o muy cerca unos de otros, porque todos ocurren dentro de la misma Base de Datos. Pero si un usuario está haciendo un SORT esos sectores estarán muy alejados de la Base de Datos y ese constante ir y venir del cabezal hará que tanto las operaciones en la Base de Datos como el SORT sean mucho más lentos de lo que deberían. Si has leído algo sobre el diseño de Sistemas Operativos recordarás que usan semáforos: le dan unos milisegundos a un proceso para que haga lo que quiere hacer, luego otros milisegundos a un segundo proceso, luego otros milisegundos a un tercer proceso, y así sucesivamente hasta regresar al primer proceso. Para los usuarios esto es transparente, creen que cada uno de sus procesos se está ejecutando simultáneamente con los demás procesos pero eso no es así (bueno, salvo que la computadora tenga varios procesadores, claro). De todas maneras, sea la computadora multi-procesador o no, el cabezal del disco duro tendrá un constante ir y venir entre los sectores usados en el SORT y los sectores usados para las otras operaciones. Eso es lento y siempre será lento, podrá aumentarse la velocidad con discos duros más veloces, pero siempre será lento.

Si están en un disco no magnético (por ejemplo, un disco SSD), entonces no hay un cabezal que se mueve, en realidad nada se mueve, pero los discos tienen una vida útil limitada que aunque va aumentando porque la tecnología mejora, siempre tiene un límite. Entonces, si además de realizar las operaciones normales (INSERT, UPDATE, DELETE, SELECT, FETCH) también le pedimos que use a ese mismo disco SSD para los SORT, los backups y los restores, la vida útil de nuestro disco SSD será mucho más corta de lo que debería ser.

Por lo tanto la conclusión es muy sencilla: la Base de Datos debe encontrarse en un disco y los archivos temporales en un disco distinto.

Ese disco debe ser físicamente distinto, no sirve que esté particionado. Si está particionado se trata del mismo disco aunque para el Sistema Operativo sean dos discos diferentes, la realidad es que sigue siendo un mismo disco físico, y eso es justamente lo que no queremos.

Artículos relacionados:

Entendiendo el contenido de un PLAN

Usando un disco RAM para aumentar la velocidad

El índice del blog Firebird21

El foro del blog Firebird21

 

Eligiendo el tamaño adecuado de las páginas de la Base de Datos

Deja un comentario

En este artículo ya hemos visto lo que son las páginas de la Base de Datos:

Entendiendo las páginas de la Base de Datos

y sabemos que esas páginas pueden tener 3 tamaños posibles:

  • 4096 bytes
  • 8192 bytes
  • 16384 bytes

¿hay alguna diferencia en el rendimiento si la Base de Datos tiene alguno de esos tamaños de página?

Sí, si tiene el tamaño adecuado entonces todas las operaciones serán más rápidas (a veces, bastante más rápidas) que si tiene un tamaño inadecuado. Las operaciones que realiza el Firebird (INSERT, UPDATE, DELETE, SELECT, FETCH) siempre afectan a una o más páginas de la Base de Datos, por lo tanto utilizar el tamaño de página adecuado es importante

entonces la pregunta ahora es ¿cuál de esos tres tamaños es el más adecuado para mi Base de Datos?

 Pues bien, la respuesta más simple es “prueba y error”. O sea, pruebas con un tamaño, luego pruebas con otro, y luego pruebas con el tercero. Comparas los desempeños y eliges el que te pareció mejor.

Desde luego que “prueba y error” es una posibilidad. Como hay solamente 3 tamaños distintos entonces es factible de realizar. Sin embargo, podemos mejorar un poco nuestro análisis para determinar el tamaño más conveniente.

  1. Tamaño de la Base de Datos. Si alguna tabla tiene o tendrá más de 100.000.000 de filas entonces elige un tamaño de página de 16384 bytes porque en tablas tan grandes los índices también serán gigantescos y por lo tanto tendrán mucha profundidad (el Firebird usa índices B-Tree, y en tales índices una profundidad mayor que 3 empieza a ser problemática).
  2. El tamaño del caché que usa la Base de Datos. Las bases de datos de Firebird tienen una memoria caché, es decir usan una porción de la memoria RAM para realizar sus procesos. Un error frecuente de los principiantes es pensar “cuanto más grande el caché, mejor”. Bien, eso no es tan así. Si fuera tan sencillo entonces el Firebird por su propia cuenta se asignaría el caché más grande posible. En un Sistema Operativo de 32 bits la mayor cantidad de memoria que puede ser direccionada es de 4 Gb (o sea, 2 elevado a la 32), pero el Windows limita esa cantidad, para que un solo proceso no esté usando toda la memoria. Por defecto, un proceso puede usar como máximo 2 Gb aunque en el archivo CONFIG.INI puede cambiarse hasta 3 Gb. Si usamos SuperServer y en el archivo FIREBIRD.CONF ponemos en la entrada DefaultDbCachePages el número 100000 y el tamaño de nuestras páginas es de 16384 bytes entonces el caché de cada Base de Datos consumirá 1.6 Gb. Lo cual implica que podremos tener abierta una sola Base de Datos, porque 1.6 Gb por 2 es 3.2 Gb, que sobrepasa el máximo de 3 Gb que el Sistema Operativo nos permite direccionar. Pero lo peor es que un caché tan gigantesco tampoco nos asegura que nuestras operaciones serán rapidísimas ¿por qué? porque el propio Sistema Operativo usa su propio caché en operaciones repetitivas de lectura en disco y por lo tanto no se usará el caché del Firebird, ocupará mucha memoria pero no se lo usará ¿Y entonces? bueno, en general un tamaño de página de 16384 bytes y un tamaño de caché moderado (o sea, alrededor de 20000) es lo más adecuado.
  3. Cantidad de filas por página. A mayor tamaño de la página, mayor cantidad de filas se pueden guardar en ella y por lo tanto la Base de Datos necesita de menos páginas. Lo normal es que si una Base de Datos tiene pocas páginas sea menos propensa a corromperse que si tiene muchas páginas. En consecuencia, un tamaño de página de 16384 bytes es preferible porque será más difícil que la Base de Datos se corrompa.
  4. Tamaño del clúster. Cuando se formatea un disco duro se debe elegir el tamaño del clúster, el cual en NTFS es de 512 bytes por defecto pero puede ser cambiado.

Si el tamaño de la página es mayor que el del clúster entonces cuando se quiere leer una página se debe leer más de un clúster desde el disco duro y eso es lento. Por ejemplo:

Tamaño de la página = 4096 bytes

Tamaño del clúster = 512 bytes

implica que leer una sola página de la Base de Datos requiere leer 8 clústers en el disco duro (ya que 512 * 8 = 4096). Lo mismo cuando se quiere escribir en una página, se requerirá escribir en 8 clústers. Y si los clústers no están contiguos eso hará aún más lenta a la operación (nosotros no podemos saber si estarán contínuos o no, porque eso es de incumbencia del Sistema Operativo).

 Si el tamaño de la página es menor que el tamaño del clúster a veces puede ser beneficioso cuando se lee, sin embargo cuando se escribe se tardará más. Por ejemplo:

Tamaño de la página = 4096 bytes

Tamaño del clúster = 8192 bytes

Como el Sistema Operativo no puede leer menos que un clúster, un clúster es lo mínimo que puede leer desde el disco duro, cada vez que lea un clúster estará trayendo 2 páginas. Eso puede ser bueno si necesitaremos luego los datos que están en la segunda página pero si no es así entonces se leyeron 4096 bytes inútiles ¿por qué? porque los primeros 4096 bytes sí los usamos, esos fueron los que pedimos, pero los siguientes 4096 nunca los usamos y por lo tanto fueron leídos inutilmente. A su vez, cuando necesitemos escribir lo haremos por duplicado porque cuando escribamos en la primera página escribiremos en el clúster y cuando escribamos la segunda página también escribiremos en el clúster.

¿Lo mejor?

Que el tamaño de la página y el tamaño del clúster sean iguales.

El tamaño adecuado puede cambiar con el tiempo

Un punto muy, pero muy importante a tener en cuenta es el siguiente: el mejor tamaño de página hoy puede no ser el mejor dentro de un mes o dentro de un año.

¿Por qué?

Porque las bases de datos son dinámicas, no son estáticas, constantemente se les están insertando, actualizando, y borrando filas. Un tamaño de página excelente cuando la Base de Datos tenía una tamaño de 50 Mb puede ser horrible cuando creció hasta tener un tamaño de 2 Gb.

Así que debemos recordar que a veces cambiar el tamaño de las páginas puede ser una muy buena alternativa para que todas las operaciones se realicen más rápidamente.

Conclusión:

Si nuestra Base de Datos tiene un tamaño de página adecuado entonces todas las operaciones que se realicen en ella (INSERT, UPDATE, DELETE, SELECT, FETCH) serán rápidas. Pero si no es así, entonces esas operaciones serán más lentas de lo que deberían.

Como hay solamente 3 tamaños de página posibles entonces es muy fácil realizar tests de “prueba y error”. Sin embargo, también podemos tener en cuenta algunos parámetros para hallar el tamaño de página más adecuado y arriba se detallan esos parámetros.

Algo importante a tener en cuenta es que el tamaño del clúster del disco duro debe ser igual al tamaño de la página de la Base de Datos, para conseguir el máximo rendimiento posible.

Artículos relacionados:

Entendiendo las páginas de la Base de Datos

El índice del blog Firebird21

El foro del blog Firebird21

SQL_RENDIMIENTO. Verificando la velocidad de las operaciones

4 comentarios

Muchas veces nos interesa saber que tan rápidas son las operaciones INSERT, UPDATE, DELETE, SELECT en una computadora Cliente o mismo en el Servidor del Firebird.

Esa información puede ser muy útil para recomendar la compra de más memoria RAM, un mejor procesador, un router de mejor calidad, etc.

La mayoría de las empresas disponen de varias computadoras y las velocidades con las cuales se realizan las operaciones en ellas no son las mismas, así que puede resultarnos muy provechoso poder determinar cuales son las computadoras lentas. Esa lentitud puede estar en el Servidor, en el Cliente, o en ambos.

Por ese motivo hice un programa que me ayudará con esa tarea y ahora lo comparto con los lectores de este blog. El enlace para descargarlo es:

http://www.mediafire.com/download/eudns020fs6xf64/SQL_RENDIMIENTO.ZIP

Está desarrollado en Visual FoxPro y tiene todos los programas fuente incluidos para que quienes conozcan dicho lenguaje puedan realizarle todas las modificaciones que crean pertinentes. También podría servirles como base para crear otros programas similares.

SQL_RENDIMIENTO1

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

Como puedes ver en la Captura 1, es bastante auto-explicativo pero si tienes alguna duda puedes preguntarme.

Para usarlo:

  1. Copia la Base de Datos de nombre VELOCIDAD.FDB en un disco duro de la computadora donde está instalado el Servidor del Firebird
  2. Crea una carpeta en la computadora Cliente
  3. Descomprime el archivo SQL_RENDIMIENTO.ZIP en esa carpeta
  4. Ejecuta el programa SQL_RENDIMIENTO.EXE

También podrías ejecutarlo desde un pen-drive pero eso no es recomendable pues allí tendrás que controlar una variable más: la velocidad del pen-drive, pues si es USB 3.0 será mucho más rápido que USB 2.0 y este será mucho más rápido que USB 1.0, y en una computadora Cliente podrías tener USB 2.0 y en otra USB 3.0 y en otra USB 1.0 y por lo tanto la comparación no sería justa.

Mientras el programa está verificando las velocidades va mostrando unos mensajes en el campo de edición “Comentarios” y al finalizar la verificación muestra un resúmen que puede servirte de guía para encontrar las fallas. Ese resúmen puede ser guardado en un archivo de texto (cuya ubicación y nombre debes colocar a continuación de: “Grabar en el archivo”).

Las demoras en el Cliente típicamente son mayores que las demoras en el Servidor porque el primero necesita que los datos vayan al Servidor y regresen y eso toma su tiempo. Es por eso que se muestran ambas demoras.

El programa califica con una nota (EXCELENTE, MUY BUENO, BUENO, ACEPTABLE, REGULAR, MALO, MUY MALO, PÉSIMO) a ambas computadoras, dependiendo del tiempo total con la cual se realizaron todas las operaciones. También da unos consejos (que en versiones posteriores podrían ampliarse) para mejorar esas velocidades. Debes tener en mente que esa calificación está basada en el procesamiento de 1.000.000 de filas y que si varías dicha cantidad de filas la calificación podría variar ya que cuantas más filas proceses el rendimiento mejorará (si multiplicas por 10 la cantidad de filas el tiempo que se demora en procesarlas el Firebird no se multiplica por 10, sino quizás por 2).

Otro punto muy importante a considerar es el siguiente: una Base de Datos totalmente vacía es mucho más rápida que una Base de Datos en la cual ya se realizaron operaciones aunque se hayan eliminado luego todas esas operaciones. ¿Qué significa esto? que siempre antes de ejecutar el programa SQL_RENDIMIENTO.EXE debes hacer un ciclo backup/restore en la Base de Datos VELOCIDAD.FDB y usar la Base de Datos restaurada para la verificación (o aún más rápido, copia la Base de Datos original, la que descargaste en el archivo .ZIP, en el Servidor) . Si no haces así, entonces cada nueva ejecución de SQL_RENDIMIENTO.EXE demorará más y eso no será justo

Entonces, antes de verificar una computadora:

  1. Copia el archivo VELOCIDAD.FDB que está en tu pen-drive en el disco duro del Servidor
  2. Crea una carpeta en el disco duro de la computadora Cliente y coloca allí a SQL_RENDIMIENTO
  3. Verifica esa computadora

Haz esto siempre, no te olvides, o los resultados mostrados no serán correctos.

Artículo relacionado:

El índice del blog Firebird21