¿Cuál es la mejor manera de almacenar una IP?

2 comentarios

Este artículo es una colaboración de Esteban Herrero, uno de los más antiguos seguidores de este blog. Gracias Esteban.

 

Si tenemos la siguiente IP 192.168.10.21 y quisiera tener un campo para almacenarla, lo más fácil sería crear un campo Char(15), pero podríamos pensar que no todas las IP tienen 15 caracteres, entonces sería mejor utilizar un VarChar(15). Lo cierto es que cada carácter almacenado ocupa  1 byte, haciendo que el almacenamiento de esta Ip lleve 13 bytes o 15 con todos los caracteres.

Pero hay una mejor forma de guardar una Ip y es utilizando un campo BigInt y sólo estaríamos utilizando 64 Bits (8 bytes). Xq no usar un campo Integer, la razón es muy simple es 32 bits y el valor máximo es 2,147,483,647 y nuestro número convertido no entraría.

 

Vamos a un ejemplo:

 

Ip 192.168.10.21

 

11000000 10101000 00001010 00010101 (en binario)

 

Ahora a Convertir:

21 * 1  +

10 * 256 +

168 * 256 * 256 +

192 * 256 * 256 * 256 = 3,232,238,101

Cómo hacerlo en Firebird? Con estos 2 procedimientos:

Execute Procedure SP_INTTOIP(3232238101);

Execute Procedure sp_iptoint(‘192.168.10.21’);

 

CREATE PROCEDURE SP_INTTOIP(

NIP BIGINT)

RETURNS(

IP VARCHAR(15))

AS

DECLARE VARIABLE Octet1 BIGINT;

DECLARE VARIABLE Octet2 BIGINT;

DECLARE VARIABLE Octet3 BIGINT;

DECLARE VARIABLE Octet4 BIGINT;

DECLARE VARIABLE RestoIP BIGINT;

BEGIN

Octet1 = :nIp / 16777216;

RestoIp = :nIp – (Octet1 * 16777216);

Octet2 = RestoIp / 65536;

RestoIp = RestoIp – (Octet2 * 65536);

Octet3 = RestoIp / 256;

Octet4 = RestoIp – (Octet3 * 256);

Ip = Cast(Octet1 as VARCHAR(3)) || ‘.’ || Cast(Octet2 as VARCHAR(3)) || ‘.’ || Cast(Octet3 as VARCHAR(3)) || ‘.’ || Cast(Octet4 as VARCHAR(3));

SUSPEND;

END;

 

CREATE PROCEDURE SP_IPTOINT(

CIP VARCHAR(15))

RETURNS(

NINT BIGINT)

AS

DECLARE VARIABLE lcColumna VARCHAR(4);

DECLARE VARIABLE nCan1 SMALLINT;

DECLARE VARIABLE nFactor BIGINT;

BEGIN

 

nInt = 0;

nFactor = 16777216;

 

WHILE ((Char_Length(cIp) > 0) AND (POSITION(‘.’ in CIP) <> 0)) DO BEGIN

EXECUTE PROCEDURE Parser(cIp, ‘.’) RETURNING_VALUES :lcColumna;

nCan1 = CHAR_LENGTH(:lcColumna) + 1;

cIp = Overlay(cIp placing ” from 1 for nCan1);

cIp = trim(cIp);

nInt = nInt + (Cast(:lcColumna as Smallint) * nFactor);

nFactor = nFactor / 256;

END

nInt = nInt + CAST(cIp as SMALLINT);

SUSPEND;

END;

 

CREATE PROCEDURE PARSER(

TCTEXTO VARCHAR(18192),

TCSEPARADOR VARCHAR(12))

RETURNS(

FTCNOMBRE VARCHAR(1024))

AS

DECLARE VARIABLE lnPosicion SMALLINT;

BEGIN

lnPosicion = Position(tcSeparador IN tcTexto);

ftcNombre = Left(tcTexto, lnPosicion – 1) ;

END;

 

Crear una función en Firebird 2.x que nos devuelva una fecha en cualquier formato

3 comentarios

A veces podríamos llegar a necesitar representar a las fechas en diferentes formatos, por ejemplo a la fecha 28 de marzo de 2017 podríamos querer presentarla como:

  • 28/03/2017
  • 03/28/2017
  • 2017/03/28
  • 28-03-2017
  • 28-MAR-2017
  • 28/MAR/2017
  • 28 de marzo de 2017
  • etc.

¿Cómo podemos obtener la fecha en el formato que nos interesa?

En Firebird no existe una función llamada DATE_FORMAT() o equivalente como sí existe en Oracle y en MySQL, por ejemplo. Pero si necesitamos esa función entonces simplemente … podemos crearla.

Ya sabemos como escribir un stored procedure y usarlo como si de una función se tratara, lo hemos visto en el artículo:

https://firebird21.wordpress.com/2014/04/20/usando-un-stored-procedure-como-una-funcion/

Entonces, usaremos esa técnica para escribir nuestra propia función DATE_FORMAT()

Listado 1.

CREATE PROCEDURE DATE_FORMAT(
   tdFechax DATE,
   tcFormat VARCHAR(128))
RETURNS(
   ftcFecha VARCHAR(128))
AS
   DECLARE VARIABLE lnDia SMALLINT;
   DECLARE VARIABLE lnMes SMALLINT;
   DECLARE VARIABLE lnAno SMALLINT;
   DECLARE VARIABLE lcMes VARCHAR(128);
BEGIN

   tcFormat = UPPER(tcFormat);

   lnDia = EXTRACT(DAY FROM tdFechax);
   lnMes = EXTRACT(MONTH FROM tdFechax);
   lnAno = EXTRACT(YEAR FROM tdFechax);

   IF (tcFormat = '%D/%M/%Y') THEN
      ftcFecha = LPAD(lnDia, 2, '0') || '/' || LPAD(lnMes, 2, '0') || '/' || lnAno;

   IF (tcFormat = '%M/%D/%Y') THEN
      ftcFecha = LPAD(lnMes, 2, '0') || '/' || LPAD(lnDia, 2, '0') || '/' || lnAno;

   IF (tcFormat = '%Y/%M/%D') THEN
      ftcFecha = lnAno || '/' || LPAD(lnMes, 2, '0') || '/' || LPAD(lnDia, 2, '0');

   IF (tcFormat = '%D-%M-%Y') THEN
      ftcFecha = LPAD(lnDia, 2, '0') || '-' || LPAD(lnMes, 2, '0') || '-' || lnAno;

   IF (tcFormat = '%M-%D-%Y') THEN
      ftcFecha = LPAD(lnMes, 2, '0') || '-' || LPAD(lnDia, 2, '0') || '-' || lnAno;

   IF (tcFormat = '%Y-%M-%D') THEN
      ftcFecha = lnAno || '-' || LPAD(lnMes, 2, '0') || '-' || LPAD(lnDia, 2, '0');

   IF (tcFormat = 'NAME') THEN BEGIN
      lcMes = '';
      lcMes = IIF(lnMes =  1, 'Enero'     , lcMes);
      lcMes = IIF(lnMes =  2, 'Febrero'   , lcMes);
      lcMes = IIF(lnMes =  3, 'Marzo'     , lcMes);
      lcMes = IIF(lnMes =  4, 'Abril'     , lcMes);
      lcMes = IIF(lnMes =  5, 'Mayo'      , lcMes);
      lcMes = IIF(lnMes =  6, 'Junio'     , lcMes);
      lcMes = IIF(lnMes =  7, 'Julio'     , lcMes);
      lcMes = IIF(lnMes =  8, 'Agosto'    , lcMes);
      lcMes = IIF(lnMes =  9, 'Septiembre', lcMes);
      lcMes = IIF(lnMes = 10, 'Octubre'   , lcMes);
      lcMes = IIF(lnMes = 11, 'Noviembre' , lcMes);
      lcMes = IIF(lnMes = 12, 'Diciembre' , lcMes);
      ftcFecha = lnDia || ' de ' || lcMes || ' de ' || lnAno;
   END

   SUSPEND;

END;

Por supuesto que podrías agregar más formatos de fecha si lo deseas, en el Listado 1. se mostraron algunas de las posibilidades.

Ahora, cuando queremos ver a una fecha con alguno de los formatos que definimos en nuestro stored procedure lo haríamos así:

Listado 2.

SELECT
   F.ftcFecha
FROM
   RDB$DATABASE
LEFT JOIN
   DATE_FORMAT(CURRENT_DATE, '%D/%M/%Y') F
      ON 1 = 1

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

Listado 3.

SELECT
   F.ftcFecha
FROM
   RDB$DATABASE
LEFT JOIN
   DATE_FORMAT(CURRENT_DATE, '%Y-%M-%D') F
      ON 1 = 1

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

Listado 4.

SELECT
   F.ftcFecha
FROM
   RDB$DATABASE
LEFT JOIN
   DATE_FORMAT(CURRENT_DATE, 'NAME') F
      ON 1 = 1

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

Conclusión:

Aunque Firebird nativamente no tiene una función DATE_FORMAT o equivalente, es bastante sencillo realizar una, tal y como hemos podido ver en este artículo. Y aunque en nuestros ejemplos hemos usado la tabla RDB$DATABASE no es ninguna obligación utilizarla, puedes usar cualquier tabla que desees, también cualquier fecha que desees, y también cualquier formato que desees. Si ese formato no se encuentra en el Listado 1., pues lo agregas y listo.

Artículos relacionados:

Usando un stored procedure como una función

El índice del blog Firebird21

El foro del blog Firebird21

Fechas aleatorias

Deja un comentario

A veces cuando estamos realizando pruebas necesitamos datos aleatorios, o sea datos que pueden ser cualesquiera, no podemos anticipar cuales serán.

Supongamos que necesitamos fechas aleatorias. Para ello, como de costumbre usaremos la función RAND(). Esta función nos devolverá un número entre 0 y 0,999999. También usaremos la función FLOOR() que nos devuelve la parte entera de un número. También usaremos la función DATEADD() que le suma un número a una fecha para devolvernos una nueva fecha, la fecha original más la cantidad de días que le hemos sumado.

Veamos algunos ejemplos:

Listado 1. Fechas entre el 1 de enero de 2017 y el 31 de marzo de 2017

SELECT
   DATEADD(FLOOR(90 * RAND()) DAY TO DATE '2017-JAN-01')
FROM
   RDB$DATABASE

Explicación:

La cantidad de días posibles es 90, así que multiplicamos a RAND() por 90. La cantidad de días debe ser un número entero, así que usamos la función FLOOR(), porque la función RAND() nos devuelve un número con decimales. Lo que estamos sumando son días así que usamos DAY, la fecha la expresamos como un string así que debemos convertirla a tipo fecha con DATE.

En síntesis, lo que estamos diciendo es: muéstrame una fecha aleatoria entre el 1 de enero de 2017 y el 31 de marzo de 2017

Listado 2. Fechas entre el 1 de enero de 2017 y el 31 de diciembre de 2017

SELECT
   DATEADD(FLOOR(365 * RAND()) DAY TO DATE '2017-JAN-01')
FROM
   RDB$DATABASE

Explicación:

Como la cantidad de días posibles es 365, entonces multiplicamos a 365 por RAND()

Listado 3. Fechas entre el 1 de abril de 2017 y el 30 de abril de 2017

SELECT
   DATEADD(FLOOR(30 * RAND()) DAY TO DATE '2017-APR-01')
FROM
   RDB$DATABASE

Explicación:

Como la cantidad de días posibles es 30, entonces multiplicamos 30 por RAND(). Como la fecha inicial es el 1 de abril de 2017, entonces escribimos esa fecha después de DATE.

Artículos relacionados:

La función DATEADD()

La función FLOOR()

La función RAND()

El índice del blog Firebird21

El foro del blog Firebird21

Liberada la versión 3.0.2 de Firebird

3 comentarios

El día 22 de marzo de 2017 fue liberada la versión 3.0.2 de Firebird, la cual ha corregido muchos “bugs” que se encontraron desde la liberación de la versión 3.0.0 y además tiene algunas mejoras en cuanto a rendimiento. Por lo tanto, si ya estás usando Firebird 3 es altamente  recomendable que descargues e instales esta nueva versión.

Puedes descargarla desde:

https://www.firebirdsql.org/en/firebird-3-0-2/

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Liberada la versión 2.5.7 de Firebird

5 comentarios

El 15 de Febrero de 2017 se liberó la versión 2.5.7 de Firebird, la cual tiene las siguientes mejoras:

  1. Se corrigió una vulnerabilidad que ocurría cuando se realizaban conexiones autenticadas. Como las conexiones autenticadas no son muy usadas por los administradores de bases de datos de Firebird el riesgo en general no era muy grande, pero igualmente es muy conveniente actualizarse a la versión 2.5.7
  2. Ahora se pueden filtrar la información y los avisos de advertencia del trace log
  3. Se agregó soporte para “TCP Loopback Fast Path”, el cual fue introducido en Windows 8 y en Server 2012, lo cual mejorará las velocidades en redes locales que usen esos sistemas operativos o versiones posteriores.

Puede ser descargado desde:

https://www.firebirdsql.org/en/firebird-2-5/

Artículos recomendados:

El índice del blog Firebird21

El foro del blog Firebird21

Ventajas y desventajas de usar servidores virtuales con Firebird

2 comentarios

Desde más o menos el año 2007 es cada vez más frecuente que las empresas e incluso los usuarios individuales cuenten con servidores virtuales. Entonces la pregunta es ¿qué tan bueno es usarlos con Firebird?

Antes de responder a esa pregunta debemos empezar por el principio y definir lo que es un servidor virtual.

Servidor virtual

Un Servidor virtual es simplemente una partición de los recursos de una computadora. Cada computadora física cuenta con memoria RAM, uno o más discos duros, uno o más núcleos, etc.

Si necesitamos una computadora que por algún motivo deba tener instalado a Windows XP y otra computadora que deba tener instalado a Windows 7, podemos ahorrar dinero, electricidad, espacio físico, etc. si instalamos ambos sistemas operativos en una sola computadora física pero particionada para que a todos los efectos parezca que se trata de 2 computadoras. Inclusive las direcciones IP serán distintas, por lo que para el mundo exterior se tratará de 2 computadoras distintas, aunque en realidad como sabemos se trata de una sola computadora.

Cada Servidor virtual tendrá acceso a una cierta cantidad de memoria RAM que se determina en el momento de la instalación. Por ejemplo, si la computadora real tiene 16 Gb de memoria RAM a la partición donde instalamos el Windows XP podríamos asignarle 4 Gb de RAM y a la partición donde instalamos el Windows 7 podríamos asignarle 12 Gb de RAM.

Desde luego que si tenemos recursos suficientes podemos tener más particiones: 3, 4, 5, 20, las que sean necesarias.

Además, los sistemas operativos que instalemos en ellas pueden ser cualesquiera que soporte el hardware. Así, podríamos tener en una partición Windows XP, en otra partición Windows 7, en otra partición Windows 10, y en otra partición Linux Ubuntu Server.

Ventajas de usar un Servidor virtual

  • Se ahorra dinero al comprar. Porque es más barato comprar una sola computadora con muchos recursos que varias computadoras con menos recursos. O sea, siempre saldrá más barato comprar una sola computadora con 16 Gb de RAM que comprar 4 computadoras con 4 Gb de RAM cada una.
  • Se ahorra electricidad. El consumo eléctrico será menor si es una sola computadora la que usa electricidad que si son varias las computadoras.
  • Se ahorra espacio físico. Porque el espacio que ocupa una sola computadora siempre será menor que el espacio que ocupan 2, 3, 5, 10, o más computadoras.
  • Se aprovecha mejor el hardware. Porque si se tienen varias computadoras físicas en algunas de ellas los recursos podrían estar mal utilizados, desperdiciándose recursos.
  • Se pueden tener programas distintos en cada Servidor virtual. No solamente el Sistema Operativo puede ser distinto, también los programas que instalemos pueden ser distintos, o distintas versiones del mismo programa.
  • Se puede verificar el rendimiento de los programas. Esto es útil para los programadores que quieren comprobar si el programa que están desarrollando funciona bien en distintos sistemas operativos o con distintas cantidades de memoria RAM, etc.
  • Cada partición es independiente de las demás particiones. Eso implica que si algún problema ocurrió en una partición las demás particiones no se verán afectadas. Por ejemplo, si por algún problema un Servidor virtual se “colgó”, los demás servidores virtuales ni se enterarán.
  • Instalar un servidor virtual es gratis o muy barato. Hay programas gratis muy buenos por lo cual no es obligatorio gastar dinero.

Desventajas de usar un Servidor virtual

  • El software de seguridad no se ejecuta bien. Los antivirus, firewalls, etc., a veces tienen problemas cuando son ejecutados desde un Servidor virtual.
  • Hay un límite en el uso de recursos. La cantidad de memoria RAM asignada, el espacio en el disco duro que puede ocupar, la cantidad de núcleos que puede utilizar, etc. tienen un límite muy inferior al que tendría si la computadora física no estuviera particionada. Por ejemplo, si la computadora física tiene 16 Gb de RAM, esos 16 Gb de RAM estarían disponibles para los programas si no se particiona; pero si se hacen 4 particiones de 4 Gb de RAM cada una, entonces ningún programa podrá utilizar más de 4 Gb de RAM.
  • Los programas que acceden al Servidor remoto se ejecutan más lentamente. Si tenemos a nuestra Base de Datos en un servidor virtual, los clientes que quieran conectarse desde otras computadoras no lo harán directamente sino que antes deberán pasar por el programa que administra a los servidores virtuales (cuyo nombre es hipervisor). Y aunque ese tiempo de demora es cada vez menor porque la tecnología avanza, siempre existe y siempre existirá.
  • Un daño físico afecta a todos los servidores. Si por ejemplo el disco duro se daña, o se quema un chip de memoria, o se quema la fuente de poder, etc., como es un único hardware el que se utiliza, este es compartido por todos los servidores virtuales, y por lo tanto todos ellos serán afectados. Así, si en un servidor virtual teníamos almacenado nuestro sitio web, en otro servidor virtual teníamos nuestro servidor de e-mails, en otro servidor virtual teníamos nuestra Base de Datos, y el disco duro se dañó y hay que reemplazarlo, ese daño afectará a todos los servidores virtuales.

Conclusión:

Como ya hemos visto, usar un servidor virtual tiene sus ventajas y sus desventajas. Por lo general no se recomienda usarlo cuando las aplicaciones constantemente están leyendo y escribiendo en el disco duro, y eso es justamente lo que ocurre con las aplicaciones que usan bases de datos. Si se usa un servidor virtual para alojar a las bases de datos, las velocidades de respuesta serán inferiores a las que se obtendrán cuando no se lo usa.

Sin embargo, los servidores virtuales son cada vez más eficientes y muchos usuarios no podrán distinguir entre ambas alternativas.

Por lo tanto, una buena política es la siguiente: si la Empresa quiere ahorrar costos, instalar y usar un servidor virtual con la Base de Datos. Si los usuarios se quejan porque la aplicación demora mucho entonces colocar la Base de Datos en un servidor real.

Artículos relacionados:

Usando Oracle VM VirtualBox

El índice del blog Firebird21

El foro del blog Firebird21

 

 

Entendiendo a GSTAT (4)

Deja un comentario

Entender como funciona el programa GSTAT es bastante largo. Ya hemos visto algo sobre él en estos artículos:

Entendiendo a GSTAT (1)

Entendiendo a GSTAT (2)

Entendiendo a GSTAT (3)

ahora, continuamos.

Opción -index

Esta es la opción que debemos elegir cuando solamente nos interesan los índices de nuestras tablas.

gstat01

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

Como es lo usual, la contraseña la extraemos de un archivo de texto y la salida del programa GSTAT la enviamos a otro archivo de texto. Esto último es para facilitarnos la tarea.

gstat02

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

En la Captura 2. vemos una parte del contenido del archivo de texto que nos muestra información sobre nuestros índices. Los nombres de los índices siempre aparecen ordenados alfabéticamente.

¿Cuál es el significado de lo que estamos viendo?

ASIENTOSCAB es el nombre de la tabla

131 es el identificador que la tabla ASIENTOSCAB tiene dentro de la tabla del sistema RDB$RELATIONS. Es en RDB$RELATIONS donde se  guardan los nombres de todas las tablas de la Base de Datos.

ASC01, ASC02, ASC03, y PK_ASIENTOSCAB son los nombres de los índices

0, 1, 2, 3, los números entre paréntesis que vemos después de los nombres de los índices son los identificadores de los índices menos 1 y nos indican el orden en el cual fueron creados, siendo 0 el primer índice que creamos, 1 el segundo índice que creamos, 2 el tercer índice que creamos y así sucesivamente. Si se creó un índice y luego se lo eliminó, el número que tenía no aparecerá en la lista.

Listado 1.

SELECT
   RDB$INDEX_ID,
   RDB$RELATION_NAME,
   RDB$INDEX_NAME
FROM
   RDB$INDICES
WHERE
   RDB$RELATION_NAME = 'ASIENTOSCAB'
ORDER BY
   RDB$INDEX_ID

gstat03

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

¿Por qué en la Captura 2. no muestra los verdaderos identificadores sino los identificadores menos 1? Es un verdadero misterio, quizás haya alguna razón valedera para ello pero es dudoso que exista. Probablemente sólo sea por costumbre.

Depth es la cantidad de indirecciones o desviaciones que hay en el árbol B-tree del índice. Lo ideal es que ese número sea como máximo 3. Si es mayor que 3 entonces el índice no será tan eficiente como podría ser ¿cómo lo solucionamos? aumentando el tamaño de la página de nuestra Base de Datos. Si por ejemplo el tamaño de la página es 4096 lo aumentamos a 8192 y volvemos a ejecutar a GSTAT con la opción -index para comprobar si Depth ahora es 1, 2, ó 3 (esos son los mejores valores que puede tener Depth). Si sigue siendo mayor que 3 entonces volvemos a aumentar el tamaño de la página de nuestra Base de Datos y ahora lo ponemos en 16384.

Leaf buckets es la cantidad de páginas que están en el nivel más bajo del árbol B-tree. Es en estas páginas donde se guardan los punteros a las filas de la tabla. En las demás páginas de índice se guardan los enlaces a otras páginas de índice.

Nodes es la cantidad total de filas en la tabla que han sido indexadas. Sin embargo, este número puede ser erróneo porque podrían aparecer filas que han sido borradas con DELETE y aún su basura no ha sido recolectada o también porque las columnas del índice cambiaron de valor. Por eso, es conveniente ejecutar a GSTAT con la opción -index solamente después de un sweep o de un ciclo backup/restore.

Average data length es el tamaño en bytes promedio de los datos de la columna (o columnas) que se indexaron. Como Firebird comprime esos datos antes de grabarlos en una página de índices, el average data length será siempre menor a la suma del tamaño de las columnas de la tabla.

Total dup es la cantidad total de duplicados que tiene un índice. Los índices que se utilizan en las restricciones Primary Key y Unique Key no admiten duplicados, pero los otros índices sí los admiten. Cuantos más duplicados haya, peor es el índice.

 Listado 2.

SELECT
   ASC_ANOEJE,
   ASC_CODSUC,
   ASC_NUMERO,
   COUNT(*)
FROM
   ASIENTOSCAB
GROUP BY
   ASC_ANOEJE,
   ASC_CODSUC,
   ASC_NUMERO

gstat05

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

gstat04

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

En la Captura 4. vemos que al ejecutar el Listado 2. se usó el índice ASC01, y en la Captura 5. vemos la cantidad de veces que los valores de ese índice aparecieron. En este caso no hay duplicados, ya que COUNT siempre nos muestra el número 1 pero en otros índices sí podría haber duplicados. El Listado 2. nos ayudará a conocer cuantos duplicados tiene nuestro índice. Recuerda que Total dup puede mostrarte una cantidad incorrecta de duplicados si no has hecho previamente un ciclo backup/restore.

Max dup es la cantidad máxima de valores duplicados que tiene un índice.

Fill distribution es una tabla de frecuencias y seguramente te recordarás de ellas si alguna vez estudiaste Estadísticas. Hay 5 filas, yendo de 20% en 20%, cada fila indicando la cantidad de páginas de índices que están completadas hasta ese porcentaje.

gstat02

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

En la Captura 6. vemos que hay 8 páginas de índices que están llenas entre un 20% y un 39%. Y hay 3 páginas de índices que están llenas entre un 40% y un 59%. La suma de 8 + 3 es 11, y siempre debe coincidir con leaf buckets.

Esta distribución es mala, estamos usando más páginas que las necesarias. ¿Cómo sabemos eso? porque no hay páginas rellenas entre un 80% y un 99%. En una buena distribución el número mayor debería estar siempre en la última fila, (es decir, en 80% a 99%). ¿Cómo conseguimos eso? Con un ciclo backup/restore y luego usando el backup restaurado.

Artículos relacionados:

Entendiendo a GSTAT (1)

Entendiendo a GSTAT (2)

Entendiendo a GSTAT (3)

El índice del blog Firebird21

El foro del blog Firebird21

Older Entries