Arquivo

Posts Tagged ‘Tunning’

Finding bottlenecks at Watson Explorer queries

If you are having problem with some Watson Explorer query, an excellent way to find bottlenecks is to perform the query with Debug and Profile options enabled, it will help you to find where exactly you have problems.

Usually, when you perform a query at WEX, you call some URL like the following (in my case port is 7205, MY_COLLECTION can be a shard, for example MY_COLLECTION_1_1):

<SERVER>:<PORT>/search?collection=MY_COLLECTION&query-xml=<%3fxml version%3d”1.0″ encoding%3d”UTF-8″%3f><operator logic%3d”and”%2f>&num=1&max=1&binning-mode=normal&start=0&show-duplicates=1&doc-axl=<%3fxml version%3d”1.0″ encoding%3d”UTF-8″%3f><document key-hash%3d”{vse%3adoc-hash()}”%2f>&binning-config=<%3fxml version%3d”1.0″ encoding%3d”UTF-8″%3f><binning-sets><binning-set bs-id%3d”VENDOR” logic%3d”or” max-bins%3d”8″ select%3d”%24VENDOR”%2f><binning-set bs-id%3d”REVENUE_USD_FACET” logic%3d”or” max-bins%3d”11″ select%3d”%24REVENUE_USD_FACET”%2f>……………field%3d”SERVICE_AREA”><field-to name%3d”SERVICE_AREA”%2f><%2ffield-map><field-map field%3d”MAX_IGS_REV_OM_BRAND_CD”><field-to name%3d”MAX_IGS_REV_OM_BRAND_CD”%2f><%2ffield-map><field-map field%3d”EMAIL_SENT”><field-to name%3d”EMAIL_SENT”%2f><%2ffield-map><field-map field%3d”REVENUE_USD_FACET”><field-to name%3d”REVENUE_USD_FACET”%2f><%2ffield-map><field-map field%3d”REVENUE”><field-to name%3d”REVENUE”%2f><%2ffield-map><field-map field%3d”CLIENT_NAME”><field-to name%3d”CLIENT_NAME”%2f><%2ffield-map><%2ffield-mapping>&sort-keys=1&score=1&shingles=0&summarize=0&gen-key=0&cache-data=0&force-binning=1&output-acls=1

If you don’t have IDEA about HOW to get the query that your Application is doing, you can enable Debug at your collection. Go to WEX console, under Configuration -> Searching -> Debugging and enable Query Logging.

Selection_355

When saved, it will start to generate log in a file called queries.log, under you collection folder, some place like:

/opt/IBM/dataexplorer/WEX-11/Engine/data/search-collections/YYY/MY_COLLECTION/crawl1/

You can check it at WEX console, under your collection configuration, tab META, field Filebase.

Ok, now, if you call this URL from your browser, appending “&debug=1&profile=1″ to the URL, you will got a XML file. Download it and lets analyze. For our case, see this:

<xpath-performances>
<xpath-performance xpath=”($FIELD_X) = ‘GBS – No’ or ($FIELD_X) = ‘GBS – Yes'” slow-ms=”10295″ n-slow=”192000″ n-fast=”0″ n-direct=”0″ n-hashes=”1″ />
</xpath-performances>

THIS tell me that JUST in order to get the field FIELD_X, I’m having slow! (I’m my case it is because my Field its an Array)

So, probably I have a problem with this field, that can be a lot, for example:
1- Null values (see my other posts)
2- Its an array to index
3- Its a long text field
4- You have a lot of possible statements using it (OR, AND, WHERE, etc)

With this information, you can go to next step, that is find a way to change the field and make it work better.

Important: I tested this with Watson Explorer 9, 10 and 11. Running at Linux Machines.

Enjoy!

Watson Explorer performance decrease with null values

Working with Watson Explorer (WEX) we saw that the search performance decrease a lot when you have null values for some field/facet. (Our WEX release at this moment is 11, we run at Linux machines and our application was written in Java, using BigIndex to index and search. (Also have pure REST version of our application in test and the problem still happen)).

For example: lets suppose that you have a facet called VENDOR in an entity called Product. Suppose that you have 5 millions Products indexed and for some of then you have nulls, in my case 2 Millions have NULL values for VENDOR field.

In this case (and similar ones), we notice a performance decrease in searches. We start to see problems when the relation of null are greater than 20%.

In order to solve the problem we have 2 options:

1- One technique we’ve used for certain dimensions is to always ensure non-null values in the index — so at index time, we either coalesce in our SQL pulls from DB2 or do transformation after ingestion to replace nulls with some predefined value. In our case we use the literal string “(no value available)”.  It: a) ensures non-null values, b) is fairly meaningful to users, and c) gives users a way to actually filter on those records if needed.

2- For some FIELDS, we can not add another values, must leave null (Business reasons) and must not show null option to user select in the facet. In this case, in the moment of search we append boolean($FIELD) to the query. For example:

General example of a slow facet query:
$VENDOR=’IBM or $VENDOR=’PEPSICO’
Rewritten query that solve the slowness:
boolean($VENDOR) and ($VENDOR=’IBM or $VENDOR=’PEPSICO’)
This way, it ignore the null values when searching and it will be very fast.
Maybe this is not the final solution and for newer WEX versions it will handle better with null values, but, this was the solution for us.
Enjoy!

Slides – Palestra: Desmistificando Tecnologias

Como prometido, seguem os slides da minha palestra: Desmistificando Tecnologias.

Performance Tip for Eclipse/RAD/RSA

A simple thing that we can do in order to have a Faster Eclipse its move our Java installation from Hard Disk to RAM (memory). In order to do this you should install Squash. Here is the steps that I follow for Ubuntu Linux, you can use to research about and do it, please, remember to change to your folders:

  • mkdir /media/ramdisk
  • mount -t tmpfs tmpfs /media/ramdisk
  • Add the following line to /etc/fstab

tmpfs /media/ramdisk tmpfs defaults,mode=1777 0 0

  • Reboot

Using the command “df -h” you should see the disk.

  • Install squashfs
    apt-get install squashfs-tools
  • Create .sqsh file
    mksquashfs /opt/java /home/julianom/jdk.sqsh
  • This is just to test, mount and see if Java is present at the folder:

mount /home/julianom/jdk.sqsh /media/ramdisk -t squashfs -o loop

  • Edit fstab – add more this lines (remember, use your own folder, change julianom)
    /home/julianom/jdk.sqsh /media/ramdisk squashfs ro,defaults,loop 0 0
  • update alternatives
    update-alternatives –install “/usr/bin/java” “java” “/media/ramdisk/bin/java” 1

There are 3 choices for the alternative java (providing /usr/bin/java).

Selection Path Priority Status
————————————————————
0 /usr/lib/j2re1.7-ibm/jre/bin/java 1200 auto mode
* 1 /media/ramdisk/bin/java 1 manual mode
2 /usr/lib/j2re1.7-ibm/jre/bin/java 1200 manual mode
3 /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java 1061 manual mode

Do not forget to change your Eclipse/RSA to run with the JRE from this place.

Enjoy!

Categorias:JAVA Tags:, , ,

Criando um Event Monitor no DB2

Muitas vezes precisamos logar os eventos que acontecem em nosso banco de dados DB2, normalmente, para monitorar desempenho, queries mais utilizadas, etc.

Criar um Event Monitor é uma das soluções mais simples e rapidas para monitoração. O procedimento abaixo mostra como criar um simples, que vai logar os eventos de seu banco:

— conecte no seu banco: db2 connect to banco user fulano using senha

— Criar o monitor de eventos
db2 “CREATE EVENT MONITOR monjmm FOR STATEMENTS WRITE TO FILE ‘c:\tmp'” — verificar se o destino c:\tmp existe e é possivel escrever no mesmo
 
— liga o monitor de eventos
db2 SET EVENT MONITOR monjmm STATE = 1
 
— Use o banco!
 
— Desligue o monitor de eventos
db2 SET EVENT MONITOR monjmm STATE = 0
 
— torne o output legivel
db2evmon -path c:\tmp > c:\tmp\filtered.out — Tem que dar permissao de leitura para os arquivos criados
 
— veja os eventos abrindo o arquivo com o bloco de notas
notepad c:\tmp\filtered.out
 
— deletar o monitor
db2 DROP EVENT MONITOR monjmm

Enjoy!

Obtendo melhor desempenho em aplicações SQL

Eventualmente vemos queixas da lentidão na execussão de Stored Procedures ou selects em geral em nossas aplicações Java, PHP, etc. Muitos fatores podem colaborar para que o desempenho seja pífio e é possível escrever um livro a respeito. De qualquer forma, vou compartilhar a seguir algumas dicas que podem ajudar. A tempo, acreditem, ainda que as pessoas saibam do que vou falar a seguir, parece que ninguem lembra no momento de implementar uma aplicação. Vamos lá:

1- Criar indices adequados
Quando temos uma busca, por exemplo: select max(data_inclusao) from tabela , vemos que o banco irá fazer uma busca pela maior data de inclusão na Tabela. Se este campo não for indice, ele varrerá toda a tabela até encontrar o maior. Caso você crie um indice para o campo, a busca irá ser muito mais rapida, podendo ser otimizada ainda mais se o indice a ser criado NESTE CASO for descendente, ou seja, do maior para o menor.

2- Comparações adequadas
Temos que dar preferência a utilizar nas clausulas “where” os indices citados acima. Caso um where demande uma busca que não seja por um indice, obviamente será muito mais lento devido a leitura que o banco irá efetuar na tabela.

3- Buffer Pool
Está é uma configuração do tanto de memória (RAM) que o banco irá utilizar. Quanto maior, mais espaço o banco terá para trabalhar com os dados em memória RAM, fazendo menos acessos ao disco (muito mais lento). Um valor aceitável para um banco de dados, é ter 95% de acerto em memória.

4- Sort Heap
É o espaço em memória disponível para o banco fazer sorts, deve ser estabelecido um valor adequado para evitar estouros de memória. Assim como o buffer pool, é um ajuste fino e vai sendo adequado de acordo com o uso da aplicação, observando-se os logs e solicitando análises de desempenho ao DBA.

5- Rotinas de expurgo
Quanto mais registros temos em uma tabela, mais trabalho o sgbd terá para encontrar informações. Uma boa prática é criar rotinas nos sistemas para expurgar dados históricos, ou seja, criar tabelas “mortas”, cuja finalidade é guardar histórico e remover estes dados se não forem necessários em tabelas quentes.

6- Particionamento de tabelas
Relacionado ao ítem anterior, se não pudermos limpar uma tabela e ela realmente tenha muitos dados, um boa idéia é particionar a mesma utilizando algum critério inteligente, por exemplo, suponha que você tenha uma tabela de VENDAS, podemos particionar a mesma num critério parecido com o abaixo:
A- Vendas realizadas a partir de 2010
B- Vendas realizadas entre 2000 e 2010
C- Vendas realizadas entre 1990 e 2000
D- Vendas realizadas antes de 1990

7- Select *
SEMPRE escreva suas buscas limitando o número de colunas, trazendo somente os dados necessários.
Limite tambem o número de linhas retornadas, sempre utilizando filtros nas clausulas WHERE.
Caso não tenha um filtro, por exemplo: o usuário não informou NOME, ENDERECO, CNPJ, ETC, para buscar um cliente, traga somente um número limitado de linhas. OBRIGUE seu usuário a utilizar critérios. É inadimissivel um “select *” em uma base de dados, ainda mais, sem Where.

8- Organização da procedure
Tenha em mente que toda clausula sql é “compilada” e o banco gera um plano de acesso para executar a mesma. Supondo que você tenha uma Stored Procedure que, dependendo dos parametros de entrada, não irá fazer chamadas a determinadas tabelas, por exemplo, se o usuário não informar a cidade do cliente, a sql não irá fazer um join com a tabela cidades. Agora imagine que em sua tabela você tem TODAS as cidades do Brasil cadastradas. Ganhamos desempenho se não envolver tal tabela na consulta (é um exemplo bobo, mas pode ser utilizado em outras escalas)!

Veja o exemplo abaixo, ele faz exatamente o que falo no ítem anterior:

CREATE PROCEDURE DBAPRD1.PSELXIMBICA(
IN PAR_CIDADE                varchar(10)
)
SPECIFIC DBAPRD1.PSELXIMBICA
DYNAMIC RESULT SETS 1

P1:BEGIN
-- declaro dois cursores, criando dois planos de acesso
DECLARE cursorListagem CURSOR WITH RETURN TO CLIENT FOR
SELECT
nome,
endereco
FROM DBAPRD1.CLIENTES;
-- este utiliza a tabela cidade, sendo bem mais lento
DECLARE cursorListagem2 CURSOR WITH RETURN TO CLIENT FOR
SELECT
A.nome,
A.endereco
FROM DBAPRD1.CLIENTES A, DBAPRD1.CIDADES B
WHERE   B.cidade LIKE PAR_CIDADE;

IF PAR_CIDADE IS NULL THEN
OPEN cursorListagem;
ELSE
OPEN cursorListagem2;
END IF;
END P1@

Enjoy!

Categorias:JAVA Tags:, , , , ,

Boas práticas para Banco de Dados

Em geral, DBAs e Desenvolvedores não conhecem muito bem boas práticas para otimizarem seu ambiente/aplicação, muitas vezes isso decorre da falta de boa formação ou falta de experiência mesmo. Para ajudar com isso, a IBM dispões de um site muito interessante com uma coleção de boas práticas para DB2, porém boa parte pode ser aplicada para outros BDs. O site fala desde instalação até escrita de aplicações.

O link para o mesmo está aqui.

Aproveitando o post, a algum tempo eu criei um artigo com boas práticas em SQL para desenvolvedores que pode ser útil, aqui está o link.

Enjoy!