OPTIMIZE DATA LOAD / OPTIMIZAR LA CARGA DE DATOS

English (Español a continuación)

Different measures can be used to optimize data loading:

1.- Reduce the number of I/O operations.

2.- Reduce the size of the data to load.

3.- Reduce the conversions made by the load rule.

4.- Adjust the size of the “index cache”.

5.- Load the data from the server.

6.- Load data in parallel.

1.- Reduce the number of I/O operations

The most effective measure to optimize data loading is to reduce the number of I/Os (read/write operations) that Essbase has to perform while loading data.

a) Essbase loads the data block by block, so it is convenient to organize the load file so that the data that is loaded in each block is grouped, thus reducing the number of I/O operations that Essbase has to perform.

  • Place the sparse dimensions first, in the same order as they are in the outline (this reduces queries to the index during loading), and then the dense dimensions.
  • Place together those data that correspond to the same block so that all the information to be loaded in each block is processed at the same time.

Let’s see an example: suppose a database with the following dimensions:

If we load the following load file:

The data with a yellow background correspond to the same block; Essbase would have to access the same block on different occasions to load the information.

The following structure is more efficient:

In this case, all the information that goes to each block is grouped, so Essbase only accesses the block once to load the data.

c) It is also more efficient if several data are loaded on the same line at the same time instead of loading only one data on each line.

  • In this case, the data loaded in the same line must correspond to a dense dimension.

Let’s see an example: the data that is loaded in each line (Sales, Cost, Margin) corresponds to the dense dimension “Data”.

2.- Reduce the size of the data to load

There are different possibilities:

a) Avoid repeating redundant members: for example, if we order the data by blocks, we can eliminate those members that are repeated.

Let’s see an example: the following text file:

It could be lightened by removing the repeated fields:

b) Round the decimals, loading only that number of decimals that is relevant.

Let’s see an example: the following text file:

We can reduce the number of decimals if we are only interested in, for example, 3 decimals.

c) When there is no data, you can change the default expression (#MISSING) for a shorter one (for example: #MI).

3.- Reduce the conversions made by the load rule

As far as possible, it is necessary to reduce the conversions that the loading rule must carry out (join fields, replace records, move the position of the columns, reject certain records…).

  • It is important to try that these changes are already included in the load file.

4.- Adjust the size of the “index cache”

Essbase keeps a record of what blocks exist and where they are on disk, information that it uses when it needs to access a particular block:

  • There is one entry for each block that exists (combination of sparse dimensions).

This information is stored in files “essxxxxx.ind” (Index Files) on the disk.

  • Each “Index File” is made up of “Index Pages”, which contain the references of the blocks (“Index Entry”): one for each block.

The “Index Cache” is a memory buffer that stores “Index Pages”: those that have been most recently visited.

  • As many files as the cache size allows are stored.

When Essbase is going to load a block it needs to locate it: first it goes to the “Index Cache” (which is faster); if its reference is not found in the “Index Cache” it goes to the disk.

  • This does not apply if the entire database is usually deleted and loaded completely: the “Index Cache” does not affect it since Essbase creates new blocks; it does not search the “Index Cache” for existing blocks.

Cache size:

  • Minimum size: 1MB
  • Maximum size: 4GB (32-bit Essbase) to 256TB (64-bit Essbase)
  • Default size: 1 MB (I/O buffer); 10MB (Direct I/0)

Recommended size: sum of the size of all “essxxx.ind” files, plus an additional % for future increases (for example, 10%); if due to system limitations it is not possible, as large as possible.

  • The total size of the “Index Files” can be checked in “Database Properties” / “Storage”.
  • This size can also be calculated approximately:
    • Size “Index Files” = Number of existing blocks * 112 bytes
    • It has a minimum size of 8 MB.

Cache statistics: the hit ratio of the “Index Cache” indicates the % of times that Essbase locates the index information in the “Index Cache” without having to go to disk.

  • It can be consulted in “Database properties” / “Statistics”.
  • The hit ratio should be close to 1 (eg 0.95 is good).

5.- Load the data from the server

It is faster when the file to be uploaded is stored on the server instead of on the user’s PC.

  • Avoids having to send information through the network from the user’s PC to the server.

6.- Load data in parallel

Data loading can be optimized using parallel loading.

a) Increase the number of threads

When Essbase proceeds to load data it uses a pipeline (data processing operations that can be executed sequentially or in parallel).

  • The data loading operation uses a pipeline consisting of 5 phases, requiring a minimum of 5 threads: one for each phase (this is the number of threads that Essbase applies by default).

The data load involves 5 phases that are (depending on whether or not the load rule is used).

No load rule:

  • Input: collect the data from the file.
  • Tokenize: separate fields with members from fields with data, creating tokens.
  • Conversion: convert the tokens, adapting them for loading.
  • Preparation: organize the data by preparing it to be put into blocks.
  • Write: put the data in blocks in memory and then write the blocks to disk (locates the correct block using the index).

With load rule:

  • Input: collect the data from the file.
  • Pre-rule: read the registers.
  • Rule: apply the conversions included in the load rule to the records.
  • Preparation: organize the data by preparing it to be put into blocks.
  • Write: put the data in blocks in memory and then write the blocks to disk (locates the correct block using the index).

Data loading can be speeded up by increasing the number of threads used. To do this, the following commands are used in the configuration file essbase.cfg

  • DLSINGLETHREADPERSTAGE [Application Name [Database Name]] FALSE
  • DLTHREADSPREPARE [Application name [Database name]] n
  • DLTHERADSWRITE [Application name [Database name]] n

In these commands the name of the application and the name of the database is optional:

  • If no application is mentioned these commands apply to all applications.
  • If an application is specified these commands apply exclusively to this application.
    • In this case a database can be specified or not: if specified, these commands apply exclusively to that database; if not specified they apply to all databases of the application.

The first of these commands (DLSINGLETHREADPERSTAGE) is used when the number of threads is to be increased: the FALSE option indicates that a single thread is not going to be used in each of the 5 load phases.

The DLTHREADSPREPARE command is used to increase the number of threads used in the preparation phase.

The DLTHERADSWRITE command is used to increase the number of threads used in the write phase.

“n”: number of threads used in each of these tasks (it can be different in both tasks).

  • It can take values ​​between 1 and 16 (32.bit platforms) or 1 and 32 (64-bit platforms).
  • The default value is 1.

For example:

  • DLSINGLETHREADPERSTAGE FALSE
  • DLTHREADSPREPARE 2
  • DLTHREADSWRITE 3

This setting would apply to all databases for all applications. In each load Essbase would use a pipeline that would use a total of 8 threads:

  • 1 thread in each of the first 3 phases.
  • 2 threads in the preparation phase.
  • 3 threads in the writing phase.

To use these threads Essbase goes to the available pool of threads, whose number is set in the essbase.cfg configuration file with the WORKERTHREADS command.

  • If the number of threads set for the parallel loading process is greater than the number of threads available in the pool, Essbase applies the default value (1 thread in each phase).

The values ​​recommended by Oracle vary depending on different parameters (type of processor, number of cores, other processes running on the server…).

  • As an example, for 32-bit (8 cores), 64-bit (16 cores) and 64-bit (32 cores) processors, it recommends 2 threads for both DLTHREADSPREPARE and DLTHREADSWRITE.

In any case, you have to monitor the use of server resources to optimize the number of threads.

  • A high number of threads may not be efficient.

b) Upload multiple files simultaneously

If the information is in several files, they can be loaded simultaneously, optimizing the use of the CPUs.

  • Each file generates its own upload pipeline.
  • If the “max_thredas” command is not used, which we will see below, the number of pipelines that Essbase applies is the lesser between the number of files that are loaded in parallel and half the number of core processors.

This simultaneous load is activated through a Maxl:

  • import database “database name” data from data_file “file name”…;

Wildcard characters (*) and/or (?) are used to define the name of the different files (they can be used in any position of the text string):

  • “ ? ”: represents any 1 character.
  • “ * “: represents any indeterminate number of characters.

When loading files in parallel, they must all use the same loading rule.

Let’s see an example: we have the following text files to load in the «sales» database:

  • File_1
  • File_1A
  • File_2
  • File_2AB

With the following command, 4 pipelines would be generated to load the 4 files.

  • import database sales data from data_file “File_*.txt”;

With the following command, 2 pipelines would be generated to load the first and third files.

  • import database sales data from data_file “File_?.txt”;

c) Other considerations

The two options discussed (a and b) can be used together.

In any case, when loads are made in parallel, the use made of the server resources must be monitored to prevent their capacity from being exceeded:

  • As a general rule, do not use more pipelines than the number of cores (core) of the processors (CPU).
  • The total number of threats used in parallel data loading can be limited by including the “using max_threads n” command in Maxl.
    • import database “database name” using max_threads n data from data_file “filename”…;
    • Being “n” the maximum number of threads.

Español

Para optimizar la carga de datos se pueden utilizar diferentes medidas:

1.- Reducir el número de operaciones I/O.

2.- Reducir el tamaño de los datos a cargar.

3.- Reducir las conversiones realizadas por la regla de carga.

4.- Ajustar el tamaño del “index cache”.

5.- Cargar los datos desde el servidor.

6.- Realizar la carga de datos en paralelo.

1.- Reducir el número de operaciones I/O

La medida más eficaz para optimizar la carga de datos es reducir el número de operaciones I/O (operaciones de lectura / escritura) que Essbase tiene que realizar mientras carga los datos.

a) Essbase carga los datos boque a bloque por lo que conviene organizar el fichero de carga de modo que los datos que se cargan en cada bloque estén agrupados, de esta manera se reduce el número de operaciones I/O que Essbase tiene que realizar.

  • Situar primero las dimensiones dispersas, en el mismo orden que están en el outline (esto reduce las consultas al índice durante la carga), y luego las dimensiones densas.
  • Situar juntos aquellos datos que corresponden al mismo bloque para que toda la información que se va a cargar en cada bloque se procese al mismo tiempo.

Veamos un ejemplo: supongamos una base con las siguientes dimensiones:

Si cargamos el siguiente fichero de carga:

Los datos con fondo amarillo corresponden a un mismo bloque; Essbase tendría que acceder al mismo bloque en diferentes ocasiones para cargar la información.

Es más eficiente la siguiente estructura:

En este caso toda la información que va a cada bloque se encuentra agrupada por lo que Essbase tan sólo accede al bloque una vez para cargar los datos.

c) También resulta más eficiente si en una misma línea se cargan varios datos a la vez en lugar de ir cargando sólo un dato en cada línea.

  • En este caso los datos que se cargan en la misma línea deben de corresponder a una dimensión densa.

Veamos un ejemplo: los datos que se cargan en cada línea (Ventas, Coste, Margen) corresponden a la dimensión densa “Datos”.

2.- Reducir el tamaño de los datos a cargar

Caben distintas posibilidades:

a) Evitar repetir miembros redundantes: por ejemplo si ordenamos los datos por bloques podemos ir eliminando aquellos miembros que se vayan repitiendo.

Veamos un ejemplo: el siguiente fichero de texto:

Se podría aligerar eliminando los campos repetidos:

b) Redondear los decimales, cargando exclusivamente aquel número de decimales que sea relevante.

Veamos un ejemplo: el siguiente fichero de texto:

Podemos reducir el número de decimales si tan sólo nos interesan, por ejemplo, 3 decimales.

c) Cuando no haya datos se puede cambiar la expresión por defecto (#MISSING) por una más reducida (por ejemplo: #MI).

3.- Reducir las conversiones realizadas por la regla de carga

En la medida de los posible hay que reducir las conversiones que debe realizar la regla de cargar (unir campos, reemplazar registros, mover la posición de las columnas, rechazar determinados registros…).

  • Hay que tratar que estos cambios ya vengan incluidos en el fichero de carga.

4.- Ajustar el tamaño del “index cache”

Essbase guarda en el disco un registro de los bloques que existen y en qué lugar se encuentran, información que utiliza cuando tiene que acceder a un bloque concreto:

  • Hay una entrada por cada bloque que existe (combinación de dimensiones dispersas).

Esta información se almacena en archivos “essxxxxx.ind” (Index Files) en el disco.

  • Cada “Index File” se compone de “Index Pages”, que contienen las referencias de los bloques (“Index Entry”): uno por cada bloque.

El “Index Cache” es un buffer de memoria que almacena “Index Pages”: los que han sido más visitados recientemente.

  • Se almacenan tantos archivos como permita el tamaño del cache.

Cuando Essbase va a cargar un bloque necesita localizarlo: primero acude al “Index Cache” (que es más rápido); si su referencia no se encuentra en el “Index Cache” acude al disco.

  • Esto no aplica si se suele borrar toda la base y cargarla completamente: el “Index Cache” no afecta ya que Essbase crea nuevos bloques; no busca en el “Index Cache” los bloques existentes.

Tamaño del cache:

  • Tamaño mínimo: 1MB
  • Tamaño máximo: 4GB (32-bit Essbase) a 256 TB (64-bit Essbase)
  • Tamaño por defecto: 1 MB (buffer I/O); 10 MB (Direct I/0)

Tamaño recomendado: suma del tamaño de todos los archivos “essxxx.ind”, más un % adicional para incrementos futuros (por ejemplo, un 10%); si por limitaciones del sistema no es posible, lo más grande posible.

  • El tamaño total de los “Index Files” se puede consultar en “Propiedades de la base de datos” / “Almacenamiento”.
  • Este tamaño también se puede calcular de forma aproximada:
  • Tamaño “Index Files” = Nº de bloques existentes * 112 bytes
  • Tiene un tamaño mínimo de 8 MB.

Estadísticas del caché: el hit ratio del “Index Cache” indica el % de veces que Essbase localiza la información del índice en el “Index Cache” sin tener que acudir al disco.

  • Se puede consultar en “Propiedades de la base de datos” / “Estadísticas”.
  • El hit ratio debería ser próximo a 1 (por ejemplo, un 0,95 es bueno).

5.- Cargar los datos desde el servidor

Es más rápido cuando el fichero que se va a cargar está almacenado en el servidor en lugar de en el PC del usuario.

  • Evita tener que enviar la información a través de la red desde el PC del usuario al servidor.

6.- Realizar la carga de datos en paralelo

La carga de datos se puede optimizar utilizando la carga en paralelo.

a) Incrementar el número de threads

Cuando Essbase procede a cargar datos utiliza un pipeline (operaciones de procesamiento de datos que se pueden ejecutar secuencialmente o en paralelo).

  • La operación de carga de datos utiliza un pipeline que consiste en 5 fases, necesitando un mínimo de 5 threads: uno por cada fase (es el número de threads que Essbase aplica por defecto).

La carga de datos implica 5 fases que son (dependiendo de si se utiliza o no regla de carga).

Sin regla de carga:

  • Input: recopilar los datos del archivo.
  • Tokenize: separar los campos con miembros de los campos con datos, creando tokens.
  • Conversión: convertir los tokens, adaptándolos para la carga.
  • Preparación: organizar los datos preparándolos para ponerlos dentro de bloques.
  • Escritura: poner los datos en bloques en memoria para a continuación escribir los bloques en el disco (localiza el bloque correcto utilizando el índice).

Con regla de carga:

  • Input: recopilar los datos del archivo.
  • Pre-rule: leer los registros.
  • Regla: aplicar a los registros las conversiones recogidas en la regla de carga.
  • Preparación: organizar los datos preparándolos para ponerlos dentro de bloques.
  • Escritura: poner los datos en bloques en memoria para a continuación escribir los bloques en el disco (localiza el bloque correcto utilizando el índice).

La carga de datos se puede acelerar incrementando el número de threads que se utiliza. Para ello se utilizan los siguientes comandos en el fichero de configuración essbase.cfg

  • DLSINGLETHREADPERSTAGE [Nombre aplicación [Nombre base de datos]] FALSE
  • DLTHREADSPREPARE [Nombre aplicación [Nombre base de datos]] n
  • DLTHERADSWRITE [Nombre aplicación [Nombre base de datos]] n

En estos comandos el nombre de la aplicación y el de base de datos es opcional:

  • Si no se menciona aplicación estos comandos se aplican a todas las aplicaciones.
  • Si se especifica una aplicación estos comandos se aplican exclusivamente a esta aplicación.
    • En este caso se puede especificar una base de datos o no: si se especifica estos comandos se aplican exclusivamente a esa base de datos; si no se especifica se aplican a todas las bases de datos de la aplicación.

El primer de estos comandos (DLSINGLETHREADPERSTAGE) se utiliza cuando se van a incrementar el número de threads: la opción FALSE indica que no se va a utilizar un único thread en cada una de las 5 fases de la carga.

El comando DLTHREADSPREPARE se utiliza para incrementar el número de threads utilizados en la fase de preparación.

El comando DLTHERADSWRITE se utiliza para incrementar el número de threads utilizados en la fase de escritura.

“n”: número de threads utilizados en cada una de estas tareas (puede ser diferente en ambas tareas).

  • Puede tomar valores entre 1 y 16 (plataformas 32.bit) o 1 y 32 (plataformas 64-bit).
  • El valor por defecto es 1.

Por ejemplo:

  • DLSINGLETHREADPERSTAGE FALSE
  • DLTHREADSPREPARE 2
  • DLTHREADSWRITE 3

Esta configuración se aplicaría a todas las bases de datos de todas las aplicaciones. En cada carga Essbase utilizaría un pipeline que emplearía un total de 8 threads:

  • 1 thread en cada una de las 3 primeras fases.
  • 2 threads en la fase de preparación.
  • 3 threads en la fase de escritura.

Para utilizar estos threads Essbase acude al pool disponible de threads, cuyo número se fija en el archivo de configuración essbase.cfg con el comando WORKERTHREADS.

  • Si el número de threads fijado para el proceso de carga en paralelo es superior al número de threads disponibles en el pool, Essbase aplica el valor por defecto (1 thread en cada fase).

Los valores recomendaos por Oracle varían en función de diferentes parámetros (tipo de procesador, número de cores, otros procesos que se ejecutan en el servidor…).

  • A título de ejemplo, para procesadores 32-bit (8 cores), 64-bit (16 cores) y 64-bit (32 cores) recomienda 2 threads tanto para DLTHREADSPREPARE como para DLTHREADSWRITE.

En todo caso, hay que monitorizar el uso de los recursos del servidor para optimizar el número de threads.

  • Un número elevado de threads puede no resultar eficiente.

b) Cargar varios archivos simultáneamente

Si la información se encuentra en varios ficheros se pueden cargar simultáneamente, optimizando el uso de las CPUs.

  • Cada fichero genera su propio pipeline de carga.
  • Si no se utiliza el comando “max_thredas”, que veremos a continuación, el número de pipelines que Essbase aplica es el menor entre el número de ficheros que se cargan en paralelo y la mitad del número de procesadores cores.

Esta carga simultanea se activa a través de un Maxl:

  • import database “nombre de la base” data from data_file “nombre del fichero”…;

Para definir el nombre de los diferentes ficheros de utilizan caracteres comodines (*) y/o (?) (se pueden utilizar en cualquier posición de la cadena de texto):

  • “ ? ”: representa  1 carácter cualquiera.
  • “ * “: representa un número indeterminado de caracteres cualquiera.

Cuando se hace una carga en paralelo de ficheros todos deben utilizar la misma regla de carga.

Veamos un ejemplo: tenemos los siguientes ficheros de texto para cargar en la base de datos “ventas”:

  • File_1
  • File_1A
  • File_2
  • File_2AB

Con el siguiente comando se generarían 4 pipelines para cargar los 4 archivos.

  • import database ventas data from data_file “File_*.txt”;

Con el siguiente comando se generarían 2 pipelines para cargar el primer y tercer fichero.

  • import database ventas data from data_file “File_?.txt”;

c) Otras consideraciones

Las dos opciones analizadas (a y b) se pueden utilizar conjuntamente.

En todo caso cuando se hacen cargas en paralelo hay que monitorizar el uso que se hace de los recursos del servidor para evitar que se pueda superar su capacidad:

  • Como regla general no utilizar más pipelines que el número de núcleos (core) de los procesadores (CPU).
  • Se puede limitar el número total de threats utilizados en la carga de datos en paralelo incluyendo en el Maxl el comando “using max_threads n”.
    • import database “nombre de la base” using max_threads n data from data_file “nombre del fichero”…;
    • Siendo “n” el número máximo de threads.